From 92a2c4c50442f91f0950ecf74f5ec3d7a88c1826 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 01:09:35 -0500 Subject: [PATCH 01/31] Add do_minimal setup to conftest --- tests/conftest.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 09de40f6..894d6b31 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,11 @@ import json from pathlib import Path +import numpy as np import pytest +from diffpy.utils.diffraction_objects import DiffractionObject + @pytest.fixture def user_filesystem(tmp_path): @@ -28,3 +31,9 @@ def _load(filename): return base_path / filename return _load + + +@pytest.fixture +def do_minimal(): + # Create an instance of DiffractionObject with minimal setup + return DiffractionObject(xarray=np.empty(0), yarray=np.empty(0), xtype="tth", wavelength=1.54) From 56541e5b6ed7e48774cf739947ccab063ca20f4e Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 01:10:35 -0500 Subject: [PATCH 02/31] Refactor and remove input_data func --- src/diffpy/utils/diffraction_objects.py | 100 ++++++------------------ 1 file changed, 26 insertions(+), 74 deletions(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index abfd44b0..23afb790 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -36,26 +36,36 @@ def _setter_wmsg(attribute): class DiffractionObject: def __init__( - self, name=None, wavelength=None, scat_quantity=None, metadata=None, xarray=None, yarray=None, xtype=None + self, + xarray, + yarray, + xtype, + wavelength, + scat_quantity="", + name="", + metadata={}, ): - if name is None: - name = "" - self.name = name - if metadata is None: - metadata = {} - self.metadata = metadata - if xtype is None: - xtype = "" + # Check xtype is valid. An empty string is the default value. + if xtype not in XQUANTITIES: + raise ValueError(_xtype_wmsg(xtype)) + + # Check xarray and yarray have the same length + if len(xarray) != len(yarray): + raise ValueError( + "'xarray' and 'yarray' must have the same length. " + "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' " + "with 'xarray' and 'yarray' of identical length." + ) + self.scat_quantity = scat_quantity self.wavelength = wavelength + self.metadata = metadata + self.name = name - if xarray is None: - xarray = np.empty(0) - if yarray is None: - yarray = np.empty(0) - + self._input_xtype = xtype self._id = uuid.uuid4() - self.input_data(xarray, yarray, xtype) + self._set_xarrays(xarray, xtype) + self._all_arrays[:, 0] = yarray def __eq__(self, other): if not isinstance(other, DiffractionObject): @@ -298,8 +308,7 @@ def get_array_index(self, value, xtype=None): the index of the value in the array """ - if xtype is None: - xtype = self._input_xtype + xtype = self._input_xtype array = self.on_xtype(xtype)[0] if len(array) == 0: raise ValueError(f"The '{xtype}' array is empty. Please ensure it is initialized.") @@ -327,63 +336,6 @@ def _set_xarrays(self, xarray, xtype): self.dmin = np.nanmin(self._all_arrays[:, 3], initial=np.inf) self.dmax = np.nanmax(self._all_arrays[:, 3], initial=0.0) - def input_data( - self, - xarray, - yarray, - xtype, - metadata={}, - scat_quantity=None, - name=None, - wavelength=None, - ): - f""" - insert a new scattering quantity into the scattering object - - Parameters - ---------- - xarray array-like of floats - the independent variable array - yarray array-like of floats - the dependent variable array - xtype string - the type of quantity for the independent variable from {*XQUANTITIES, } - metadata, scat_quantity, name and wavelength are optional. They have the same - meaning as in the constructor. Values will only be overwritten if non-empty values are passed. - - Returns - ------- - Nothing. Updates the object in place. - - """ - - # Check xarray and yarray have the same length - if len(xarray) != len(yarray): - raise ValueError( - "'xarray' and 'yarray' must have the same length. " - "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' " - "with 'xarray' and 'yarray' of identical length." - ) - - self._set_xarrays(xarray, xtype) - self._all_arrays[:, 0] = yarray - self._input_xtype = xtype - # only update these optional values if non-empty quantities are passed to avoid overwriting - # valid data inadvertently - if metadata: - self.metadata = metadata - if scat_quantity is not None: - self.scat_quantity = scat_quantity - if name is not None: - self.name = name - if wavelength is not None: - self.wavelength = wavelength - - # Check xtype is valid. An empty string is the default value. - if xtype != "": - if xtype not in XQUANTITIES: - raise ValueError(_xtype_wmsg(xtype)) - def _get_original_array(self): if self._input_xtype in QQUANTITIES: return self.on_q(), "q" From 1144d1f9c989d16ce1f2cd1ef4e7ff6642461d44 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 01:11:00 -0500 Subject: [PATCH 03/31] Re-organize test with required parameters of xarray, yarray, wavelength, and xtype --- tests/test_diffraction_objects.py | 116 +++++++++++------------------- 1 file changed, 40 insertions(+), 76 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 50080550..089dfc2a 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -11,11 +11,6 @@ from diffpy.utils.diffraction_objects import XQUANTITIES, DiffractionObject params = [ - ( # Default - {}, - {}, - True, - ), ( # Compare same attributes { "name": "same", @@ -41,8 +36,8 @@ { "name": "something", "scat_quantity": "", - "wavelength": None, - "xtype": "", + "wavelength": 0.71, + "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, @@ -50,8 +45,8 @@ { "name": "something else", "scat_quantity": "", - "wavelength": None, - "xtype": "", + "wavelength": 0.71, + "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, @@ -62,15 +57,15 @@ { "scat_quantity": "", "wavelength": 0.71, - "xtype": "", + "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, }, { "scat_quantity": "", - "wavelength": None, - "xtype": "", + "wavelength": 0.42, + "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, @@ -81,7 +76,7 @@ { "scat_quantity": "", "wavelength": 0.71, - "xtype": "", + "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, @@ -89,7 +84,7 @@ { "scat_quantity": "", "wavelength": 0.711, - "xtype": "", + "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, @@ -99,16 +94,16 @@ ( # Different scat_quantity { "scat_quantity": "x-ray", - "wavelength": None, - "xtype": "", + "xtype": "tth", + "wavelength": 0.71, "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, }, { "scat_quantity": "neutron", - "wavelength": None, - "xtype": "", + "xtype": "tth", + "wavelength": 0.71, "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, @@ -118,16 +113,16 @@ ( # Different on_q { "scat_quantity": "", - "wavelength": None, "xtype": "q", + "wavelength": 0.71, "xarray": np.array([1.0, 2.0]), "yarray": np.array([100.0, 200.0]), "metadata": {}, }, { "scat_quantity": "", - "wavelength": None, "xtype": "q", + "wavelength": 0.71, "xarray": np.array([3.0, 4.0]), "yarray": np.array([100.0, 200.0]), "metadata": {"thing1": 1, "thing2": "thing2"}, @@ -137,16 +132,16 @@ ( # Different metadata { "scat_quantity": "", - "wavelength": None, - "xtype": "", + "xtype": "q", + "wavelength": 0.71, "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 0, "thing2": "thing2"}, }, { "scat_quantity": "", - "wavelength": None, - "xtype": "", + "xtype": "q", + "wavelength": 0.71, "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, @@ -171,7 +166,7 @@ def test_on_xtype(): assert np.allclose(test.on_xtype("d"), [np.array([12.13818, 6.28319]), np.array([1, 2])]) -def test_init_invalid_xtype(): +def test_init_invalid_xtype(do_minimal): with pytest.raises( ValueError, match=re.escape( @@ -179,7 +174,7 @@ def test_init_invalid_xtype(): f"Please rerun specifying an xtype from {*XQUANTITIES, }" ), ): - DiffractionObject(xtype="invalid_type") + return DiffractionObject(xarray=np.empty(0), yarray=np.empty(0), xtype="invalid_type", wavelength=1.54) params_index = [ @@ -241,40 +236,6 @@ def test_dump(tmp_path, mocker): tc_params = [ - ( - {}, - { - "_all_arrays": np.empty(shape=(0, 4)), # instantiate empty - "metadata": {}, - "_input_xtype": "", - "name": "", - "scat_quantity": None, - "qmin": np.float64(np.inf), - "qmax": np.float64(0.0), - "tthmin": np.float64(np.inf), - "tthmax": np.float64(0.0), - "dmin": np.float64(np.inf), - "dmax": np.float64(0.0), - "wavelength": None, - }, - ), - ( # instantiate just non-array attributes - {"name": "test", "scat_quantity": "x-ray", "metadata": {"thing": "1", "another": "2"}}, - { - "_all_arrays": np.empty(shape=(0, 4)), - "metadata": {"thing": "1", "another": "2"}, - "_input_xtype": "", - "name": "test", - "scat_quantity": "x-ray", - "qmin": np.float64(np.inf), - "qmax": np.float64(0.0), - "tthmin": np.float64(np.inf), - "tthmax": np.float64(0.0), - "dmin": np.float64(np.inf), - "dmax": np.float64(0.0), - "wavelength": None, - }, - ), ( # instantiate just array attributes { "xarray": np.array([0.0, 90.0, 180.0]), @@ -293,7 +254,7 @@ def test_dump(tmp_path, mocker): "metadata": {}, "_input_xtype": "tth", "name": "", - "scat_quantity": None, + "scat_quantity": "", "qmin": np.float64(0.0), "qmax": np.float64(1.0), "tthmin": np.float64(0.0), @@ -339,6 +300,9 @@ def test_dump(tmp_path, mocker): def test_constructor(inputs, expected): actual = DiffractionObject(**inputs).__dict__ diff = DeepDiff(actual, expected, ignore_order=True, significant_digits=13, exclude_paths="root['_id']") + print("Print diff") + print(diff) + # {'dictionary_item_added': ["root['name']", "root['scat_quantity']"]} assert diff == {} @@ -359,8 +323,8 @@ def test_all_array_getter(): assert np.allclose(actual_do.all_arrays, expected_all_arrays) -def test_all_array_setter(): - actual_do = DiffractionObject() +def test_all_array_setter(do_minimal): + actual_do = do_minimal # Attempt to directly modify the property with pytest.raises( @@ -371,21 +335,21 @@ def test_all_array_setter(): actual_do.all_arrays = np.empty((4, 4)) -def test_id_getter(): - do = DiffractionObject() +def test_id_getter(do_minimal): + do = do_minimal assert hasattr(do, "id") assert isinstance(do.id, UUID) assert len(str(do.id)) == 36 -def test_id_getter_with_mock(mocker): +def test_id_getter_with_mock(mocker, do_minimal): mocker.patch.object(DiffractionObject, "id", new_callable=lambda: UUID("d67b19c6-3016-439f-81f7-cf20a04bee87")) - do = DiffractionObject() + do = do_minimal assert do.id == UUID("d67b19c6-3016-439f-81f7-cf20a04bee87") -def test_id_setter_error(): - do = DiffractionObject() +def test_id_setter_error(do_minimal): + do = do_minimal with pytest.raises( AttributeError, @@ -401,18 +365,18 @@ def test_xarray_yarray_length_mismatch(): "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' " "with 'xarray' and 'yarray' of identical length", ): - DiffractionObject(xarray=np.array([1.0, 2.0]), yarray=np.array([0.0, 0.0, 0.0])) + DiffractionObject( + xarray=np.array([1.0, 2.0]), yarray=np.array([0.0, 0.0, 0.0]), xtype="tth", wavelength=1.54 + ) -def test_input_xtype_getter(): - do = DiffractionObject(xtype="tth") +def test_input_xtype_getter(do_minimal): + do = do_minimal assert do.input_xtype == "tth" -def test_input_xtype_setter_error(): - do = DiffractionObject(xtype="tth") - - # Attempt to directly modify the property +def test_input_xtype_setter_error(do_minimal): + do = do_minimal with pytest.raises( AttributeError, match="Direct modification of attribute 'input_xtype' is not allowed. " From e7b4dc2b53f0007d7f36715ba2d57fcedf37254b Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 01:15:09 -0500 Subject: [PATCH 04/31] Add input public data back to init func --- src/diffpy/utils/diffraction_objects.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index 23afb790..2eddc8a6 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -45,6 +45,12 @@ def __init__( name="", metadata={}, ): + + self._id = uuid.uuid4() + self.input_data(xarray, yarray, xtype, wavelength, scat_quantity, name, metadata) + + def input_data(self, xarray, yarray, xtype, wavelength, scat_quantity, name, metadata): + # Check xtype is valid. An empty string is the default value. if xtype not in XQUANTITIES: raise ValueError(_xtype_wmsg(xtype)) @@ -63,7 +69,7 @@ def __init__( self.name = name self._input_xtype = xtype - self._id = uuid.uuid4() + self._set_xarrays(xarray, xtype) self._all_arrays[:, 0] = yarray From 6dc2738613ff034efe26ad74cdb651a0ea5e0527 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 01:16:37 -0500 Subject: [PATCH 05/31] Remove print diff function in pytest for debugging --- tests/test_diffraction_objects.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 089dfc2a..9118fad8 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -300,9 +300,6 @@ def test_dump(tmp_path, mocker): def test_constructor(inputs, expected): actual = DiffractionObject(**inputs).__dict__ diff = DeepDiff(actual, expected, ignore_order=True, significant_digits=13, exclude_paths="root['_id']") - print("Print diff") - print(diff) - # {'dictionary_item_added': ["root['name']", "root['scat_quantity']"]} assert diff == {} @@ -348,6 +345,18 @@ def test_id_getter_with_mock(mocker, do_minimal): assert do.id == UUID("d67b19c6-3016-439f-81f7-cf20a04bee87") + def input_data( + self, + xarray, + yarray, + xtype, + metadata={}, + scat_quantity=None, + name=None, + wavelength=None, + ): + + def test_id_setter_error(do_minimal): do = do_minimal From 50b7d0d9c867d060d6be6243920653f12fa46a70 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 01:30:32 -0500 Subject: [PATCH 06/31] Update input_data docstrings for clarity --- src/diffpy/utils/diffraction_objects.py | 28 ++++++++++++++++++++++++- tests/test_diffraction_objects.py | 12 ----------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index 2eddc8a6..d49be5d2 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -49,7 +49,33 @@ def __init__( self._id = uuid.uuid4() self.input_data(xarray, yarray, xtype, wavelength, scat_quantity, name, metadata) - def input_data(self, xarray, yarray, xtype, wavelength, scat_quantity, name, metadata): + def input_data(self, xarray, yarray, xtype, wavelength, scat_quantity=None, name="", metadata={}): + """ + Insert a new scattering quantity into the scattering object. + + Parameters + ---------- + xarray : array-like + The independent variable array (e.g., q, tth, or d). + yarray : array-like + The dependent variable array corresponding to intensity values + xtype : str + The type of the independent variable in `xarray`. Must be one of {*XQUANTITIES}, + such as "q", "tth", or "d". + wavelength : float + The wavelength of the incoming beam, specified in angstroms (Å). + scat_quantity : str, optional + The type of scattering experiment (e.g., "x-ray", "neutron"). Default is "". + name : str, optional + The name or label for the scattering data. Default is an empty string "". + metadata : dict, optional + The additional metadata associated with the diffraction object. Default is {}. + + Returns + ------- + None + This method updates the object in place and does not return a value. + """ # Check xtype is valid. An empty string is the default value. if xtype not in XQUANTITIES: diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 9118fad8..d21591cf 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -345,18 +345,6 @@ def test_id_getter_with_mock(mocker, do_minimal): assert do.id == UUID("d67b19c6-3016-439f-81f7-cf20a04bee87") - def input_data( - self, - xarray, - yarray, - xtype, - metadata={}, - scat_quantity=None, - name=None, - wavelength=None, - ): - - def test_id_setter_error(do_minimal): do = do_minimal From 291cc89852387e32f326559557657893cabfa62e Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 01:31:27 -0500 Subject: [PATCH 07/31] Add quotation marks around q, tth, d in docstrings --- src/diffpy/utils/diffraction_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index d49be5d2..c3c1d3ee 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -56,7 +56,7 @@ def input_data(self, xarray, yarray, xtype, wavelength, scat_quantity=None, name Parameters ---------- xarray : array-like - The independent variable array (e.g., q, tth, or d). + The independent variable array (e.g., "q", "tth", or "d"). yarray : array-like The dependent variable array corresponding to intensity values xtype : str From b8a9adc52d69d197966014aabed7b4817f99c145 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 01:32:10 -0500 Subject: [PATCH 08/31] Use empty string for default scattering quantity --- src/diffpy/utils/diffraction_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index c3c1d3ee..7e704df1 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -49,7 +49,7 @@ def __init__( self._id = uuid.uuid4() self.input_data(xarray, yarray, xtype, wavelength, scat_quantity, name, metadata) - def input_data(self, xarray, yarray, xtype, wavelength, scat_quantity=None, name="", metadata={}): + def input_data(self, xarray, yarray, xtype, wavelength, scat_quantity="", name="", metadata={}): """ Insert a new scattering quantity into the scattering object. From e3c52089a5a31f450eb819b4550894c191f4c586 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 01:35:05 -0500 Subject: [PATCH 09/31] Final cleanup on input_data docstrings --- src/diffpy/utils/diffraction_objects.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index 7e704df1..fc86984e 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -58,14 +58,14 @@ def input_data(self, xarray, yarray, xtype, wavelength, scat_quantity="", name=" xarray : array-like The independent variable array (e.g., "q", "tth", or "d"). yarray : array-like - The dependent variable array corresponding to intensity values + The dependent variable array corresponding to intensity values. xtype : str The type of the independent variable in `xarray`. Must be one of {*XQUANTITIES}, such as "q", "tth", or "d". wavelength : float The wavelength of the incoming beam, specified in angstroms (Å). scat_quantity : str, optional - The type of scattering experiment (e.g., "x-ray", "neutron"). Default is "". + The type of scattering experiment (e.g., "x-ray", "neutron"). Default is an empty string "". name : str, optional The name or label for the scattering data. Default is an empty string "". metadata : dict, optional @@ -95,7 +95,6 @@ def input_data(self, xarray, yarray, xtype, wavelength, scat_quantity="", name=" self.name = name self._input_xtype = xtype - self._set_xarrays(xarray, xtype) self._all_arrays[:, 0] = yarray From de6f12d8fe5f53ea1bded2da97d58bfc1ebb99b8 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 13:41:39 -0500 Subject: [PATCH 10/31] make wavelength optional, test invalid init args --- src/diffpy/utils/diffraction_objects.py | 87 +++++++++++++++---------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index 8765a258..ed42ba83 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -35,49 +35,64 @@ def _setter_wmsg(attribute): class DiffractionObject: + """ + Initialize a DiffractionObject instance. + + Parameters + ---------- + xarray : array-like + The independent variable array containing "q", "tth", or "d" values. + yarray : array-like + The dependent variable array corresponding to intensity values. + xtype : str + The type of the independent variable in `xarray`. Must be one of {*XQUANTITIES}. + wavelength : float, optional + The wavelength of the incoming beam, specified in angstroms (Å). Default is none. + scat_quantity : str, optional + The type of scattering experiment (e.g., "x-ray", "neutron"). Default is an empty string "". + name : str, optional + The name or label for the scattering data. Default is an empty string "". + metadata : dict, optional + The additional metadata associated with the diffraction object. Default is {}. + + Examples + -------- + Create a DiffractionObject for X-ray scattering data: + + >>> import numpy as np + >>> from diffpy.utils.diffraction_objects import DiffractionObject + ... + >>> x = np.array([0.12, 0.24, 0.31, 0.4]) # independent variable (e.g., q) + >>> y = np.array([10, 20, 40, 60]) # intensity valuester + >>> metadata = { + ... "package_info": {"version": "3.6.0"} + ... } + >>> do = DiffractionObject( + ... xarray=x, + ... yarray=y, + ... xtype="q", + ... wavelength=1.54, + ... scat_quantity="x-ray", + ... metadata=metadata + ... ) + >>> print(do.metadata) + """ + def __init__( self, xarray, yarray, xtype, - wavelength, + wavelength=None, scat_quantity="", name="", metadata={}, ): self._id = uuid.uuid4() - self.input_data(xarray, yarray, xtype, wavelength, scat_quantity, name, metadata) - - def input_data(self, xarray, yarray, xtype, wavelength, scat_quantity="", name="", metadata={}): - """ - Insert a new scattering quantity into the scattering object. - - Parameters - ---------- - xarray : array-like - The independent variable array (e.g., "q", "tth", or "d"). - yarray : array-like - The dependent variable array corresponding to intensity values. - xtype : str - The type of the independent variable in `xarray`. Must be one of {*XQUANTITIES}, - such as "q", "tth", or "d". - wavelength : float - The wavelength of the incoming beam, specified in angstroms (Å). - scat_quantity : str, optional - The type of scattering experiment (e.g., "x-ray", "neutron"). Default is an empty string "". - name : str, optional - The name or label for the scattering data. Default is an empty string "". - metadata : dict, optional - The additional metadata associated with the diffraction object. Default is {}. - - Returns - ------- - None - This method updates the object in place and does not return a value. - """ + self._input_data(xarray, yarray, xtype, wavelength, scat_quantity, name, metadata) - # Check xtype is valid. An empty string is the default value. + def _input_data(self, xarray, yarray, xtype, wavelength, scat_quantity, name, metadata): if xtype not in XQUANTITIES: raise ValueError(_xtype_wmsg(xtype)) @@ -93,10 +108,9 @@ def input_data(self, xarray, yarray, xtype, wavelength, scat_quantity="", name=" self.wavelength = wavelength self.metadata = metadata self.name = name - self._input_xtype = xtype - self._set_xarrays(xarray, xtype) - self._all_arrays[:, 0] = yarray + self._set_arrays(xarray, xtype, yarray) + self._set_min_max_xarray() def __eq__(self, other): if not isinstance(other, DiffractionObject): @@ -346,8 +360,9 @@ def get_array_index(self, value, xtype=None): i = (np.abs(array - value)).argmin() return i - def _set_xarrays(self, xarray, xtype): + def _set_arrays(self, xarray, xtype, yarray): self._all_arrays = np.empty(shape=(len(xarray), 4)) + self._all_arrays[:, 0] = yarray if xtype.lower() in QQUANTITIES: self._all_arrays[:, 1] = xarray self._all_arrays[:, 2] = q_to_tth(xarray, self.wavelength) @@ -360,6 +375,8 @@ def _set_xarrays(self, xarray, xtype): self._all_arrays[:, 3] = xarray self._all_arrays[:, 1] = d_to_q(xarray) self._all_arrays[:, 2] = d_to_tth(xarray, self.wavelength) + + def _set_min_max_xarray(self): self.qmin = np.nanmin(self._all_arrays[:, 1], initial=np.inf) self.qmax = np.nanmax(self._all_arrays[:, 1], initial=0.0) self.tthmin = np.nanmin(self._all_arrays[:, 2], initial=np.inf) From 7ccebe86ea05baf1db7d24416809f2992f1fb8f0 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 13:41:59 -0500 Subject: [PATCH 11/31] Add wavelength user behavior back --- tests/test_diffraction_objects.py | 47 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 7f18f29e..7ef5f945 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -15,7 +15,6 @@ { "name": "same", "scat_quantity": "x-ray", - "wavelength": 0.71, "xtype": "q", "xarray": np.array([1.0, 2.0]), "yarray": np.array([100.0, 200.0]), @@ -24,7 +23,6 @@ { "name": "same", "scat_quantity": "x-ray", - "wavelength": 0.71, "xtype": "q", "xarray": np.array([1.0, 2.0]), "yarray": np.array([100.0, 200.0]), @@ -35,8 +33,6 @@ ( # Different names { "name": "something", - "scat_quantity": "", - "wavelength": 0.71, "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), @@ -44,8 +40,6 @@ }, { "name": "something else", - "scat_quantity": "", - "wavelength": 0.71, "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), @@ -55,7 +49,6 @@ ), ( # Different wavelengths { - "scat_quantity": "", "wavelength": 0.71, "xtype": "tth", "xarray": np.empty(0), @@ -63,7 +56,6 @@ "metadata": {"thing1": 1, "thing2": "thing2"}, }, { - "scat_quantity": "", "wavelength": 0.42, "xtype": "tth", "xarray": np.empty(0), @@ -74,7 +66,6 @@ ), ( # Different wavelengths { - "scat_quantity": "", "wavelength": 0.71, "xtype": "tth", "xarray": np.empty(0), @@ -82,7 +73,6 @@ "metadata": {"thing1": 1, "thing2": "thing2"}, }, { - "scat_quantity": "", "wavelength": 0.711, "xtype": "tth", "xarray": np.empty(0), @@ -112,15 +102,12 @@ ), ( # Different on_q { - "scat_quantity": "", "xtype": "q", "wavelength": 0.71, "xarray": np.array([1.0, 2.0]), "yarray": np.array([100.0, 200.0]), - "metadata": {}, }, { - "scat_quantity": "", "xtype": "q", "wavelength": 0.71, "xarray": np.array([3.0, 4.0]), @@ -131,7 +118,6 @@ ), ( # Different metadata { - "scat_quantity": "", "xtype": "q", "wavelength": 0.71, "xarray": np.empty(0), @@ -139,7 +125,6 @@ "metadata": {"thing1": 0, "thing2": "thing2"}, }, { - "scat_quantity": "", "xtype": "q", "wavelength": 0.71, "xarray": np.empty(0), @@ -166,7 +151,7 @@ def test_on_xtype(): assert np.allclose(do.on_xtype("d"), [np.array([12.13818, 6.28319]), np.array([1, 2])]) -def test_init_invalid_xtype(do_minimal): +def test_init_invalid_xtype(): with pytest.raises( ValueError, match=re.escape( @@ -387,7 +372,8 @@ def test_dump(tmp_path, mocker): assert actual == expected -tc_params = [ + +@pytest.mark.parametrize("init_args, expected_do_dict", [ ( # instantiate just array attributes { "xarray": np.array([0.0, 90.0, 180.0]), @@ -445,14 +431,27 @@ def test_dump(tmp_path, mocker): "wavelength": 4.0 * np.pi, }, ), -] +]) +def test_init_valid(init_args, expected_do_dict): + actual_do_dict = DiffractionObject(**init_args).__dict__ + diff = DeepDiff(actual_do_dict, expected_do_dict, ignore_order=True, significant_digits=13, exclude_paths="root['_id']") + assert diff == {} -@pytest.mark.parametrize("inputs, expected", tc_params) -def test_constructor(inputs, expected): - actual = DiffractionObject(**inputs).__dict__ - diff = DeepDiff(actual, expected, ignore_order=True, significant_digits=13, exclude_paths="root['_id']") - assert diff == {} + +@pytest.mark.parametrize("init_args, error_message", [ + ( # UC1: no arguments provided + {}, + "missing 3 required positional arguments: 'xarray', 'yarray', and 'xtype'", + ), + ( # UC2: only xarray and yarray provided + {"xarray": np.array([0.0, 90.0]), "yarray": np.array([0.0, 90.0])}, + "missing 1 required positional argument: 'xtype'", + ), +]) +def test_init_invalid_args(init_args, error_message): + with pytest.raises(TypeError, match=error_message): + DiffractionObject(**init_args) def test_all_array_getter(): @@ -473,7 +472,7 @@ def test_all_array_getter(): def test_all_array_setter(do_minimal): - actual_do = do_minimal + do = do_minimal # Attempt to directly modify the property with pytest.raises( AttributeError, From 2752578001a76e8458e02a966e7f2adfb7ce3099 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Dec 2024 18:42:08 +0000 Subject: [PATCH 12/31] [pre-commit.ci] auto fixes from pre-commit hooks --- tests/test_diffraction_objects.py | 150 ++++++++++++++++-------------- 1 file changed, 78 insertions(+), 72 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 7ef5f945..9fef29fa 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -372,83 +372,89 @@ def test_dump(tmp_path, mocker): assert actual == expected - -@pytest.mark.parametrize("init_args, expected_do_dict", [ - ( # instantiate just array attributes - { - "xarray": np.array([0.0, 90.0, 180.0]), - "yarray": np.array([1.0, 2.0, 3.0]), - "xtype": "tth", - "wavelength": 4.0 * np.pi, - }, - { - "_all_arrays": np.array( - [ - [1.0, 0.0, 0.0, np.float64(np.inf)], - [2.0, 1.0 / np.sqrt(2), 90.0, np.sqrt(2) * 2 * np.pi], - [3.0, 1.0, 180.0, 1.0 * 2 * np.pi], - ] - ), - "metadata": {}, - "_input_xtype": "tth", - "name": "", - "scat_quantity": "", - "qmin": np.float64(0.0), - "qmax": np.float64(1.0), - "tthmin": np.float64(0.0), - "tthmax": np.float64(180.0), - "dmin": np.float64(2 * np.pi), - "dmax": np.float64(np.inf), - "wavelength": 4.0 * np.pi, - }, - ), - ( # instantiate just array attributes - { - "xarray": np.array([np.inf, 2 * np.sqrt(2) * np.pi, 2 * np.pi]), - "yarray": np.array([1.0, 2.0, 3.0]), - "xtype": "d", - "wavelength": 4.0 * np.pi, - "scat_quantity": "x-ray", - }, - { - "_all_arrays": np.array( - [ - [1.0, 0.0, 0.0, np.float64(np.inf)], - [2.0, 1.0 / np.sqrt(2), 90.0, np.sqrt(2) * 2 * np.pi], - [3.0, 1.0, 180.0, 1.0 * 2 * np.pi], - ] - ), - "metadata": {}, - "_input_xtype": "d", - "name": "", - "scat_quantity": "x-ray", - "qmin": np.float64(0.0), - "qmax": np.float64(1.0), - "tthmin": np.float64(0.0), - "tthmax": np.float64(180.0), - "dmin": np.float64(2 * np.pi), - "dmax": np.float64(np.inf), - "wavelength": 4.0 * np.pi, - }, - ), -]) +@pytest.mark.parametrize( + "init_args, expected_do_dict", + [ + ( # instantiate just array attributes + { + "xarray": np.array([0.0, 90.0, 180.0]), + "yarray": np.array([1.0, 2.0, 3.0]), + "xtype": "tth", + "wavelength": 4.0 * np.pi, + }, + { + "_all_arrays": np.array( + [ + [1.0, 0.0, 0.0, np.float64(np.inf)], + [2.0, 1.0 / np.sqrt(2), 90.0, np.sqrt(2) * 2 * np.pi], + [3.0, 1.0, 180.0, 1.0 * 2 * np.pi], + ] + ), + "metadata": {}, + "_input_xtype": "tth", + "name": "", + "scat_quantity": "", + "qmin": np.float64(0.0), + "qmax": np.float64(1.0), + "tthmin": np.float64(0.0), + "tthmax": np.float64(180.0), + "dmin": np.float64(2 * np.pi), + "dmax": np.float64(np.inf), + "wavelength": 4.0 * np.pi, + }, + ), + ( # instantiate just array attributes + { + "xarray": np.array([np.inf, 2 * np.sqrt(2) * np.pi, 2 * np.pi]), + "yarray": np.array([1.0, 2.0, 3.0]), + "xtype": "d", + "wavelength": 4.0 * np.pi, + "scat_quantity": "x-ray", + }, + { + "_all_arrays": np.array( + [ + [1.0, 0.0, 0.0, np.float64(np.inf)], + [2.0, 1.0 / np.sqrt(2), 90.0, np.sqrt(2) * 2 * np.pi], + [3.0, 1.0, 180.0, 1.0 * 2 * np.pi], + ] + ), + "metadata": {}, + "_input_xtype": "d", + "name": "", + "scat_quantity": "x-ray", + "qmin": np.float64(0.0), + "qmax": np.float64(1.0), + "tthmin": np.float64(0.0), + "tthmax": np.float64(180.0), + "dmin": np.float64(2 * np.pi), + "dmax": np.float64(np.inf), + "wavelength": 4.0 * np.pi, + }, + ), + ], +) def test_init_valid(init_args, expected_do_dict): actual_do_dict = DiffractionObject(**init_args).__dict__ - diff = DeepDiff(actual_do_dict, expected_do_dict, ignore_order=True, significant_digits=13, exclude_paths="root['_id']") + diff = DeepDiff( + actual_do_dict, expected_do_dict, ignore_order=True, significant_digits=13, exclude_paths="root['_id']" + ) assert diff == {} - -@pytest.mark.parametrize("init_args, error_message", [ - ( # UC1: no arguments provided - {}, - "missing 3 required positional arguments: 'xarray', 'yarray', and 'xtype'", - ), - ( # UC2: only xarray and yarray provided - {"xarray": np.array([0.0, 90.0]), "yarray": np.array([0.0, 90.0])}, - "missing 1 required positional argument: 'xtype'", - ), -]) +@pytest.mark.parametrize( + "init_args, error_message", + [ + ( # UC1: no arguments provided + {}, + "missing 3 required positional arguments: 'xarray', 'yarray', and 'xtype'", + ), + ( # UC2: only xarray and yarray provided + {"xarray": np.array([0.0, 90.0]), "yarray": np.array([0.0, 90.0])}, + "missing 1 required positional argument: 'xtype'", + ), + ], +) def test_init_invalid_args(init_args, error_message): with pytest.raises(TypeError, match=error_message): DiffractionObject(**init_args) From d1f767b98c7c80a5688bc2bb0077c4bf440bb673 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 13:43:39 -0500 Subject: [PATCH 13/31] Restore wavelenght none in one of the test cases --- tests/test_diffraction_objects.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 9fef29fa..9b6769b7 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -103,13 +103,11 @@ ( # Different on_q { "xtype": "q", - "wavelength": 0.71, "xarray": np.array([1.0, 2.0]), "yarray": np.array([100.0, 200.0]), }, { "xtype": "q", - "wavelength": 0.71, "xarray": np.array([3.0, 4.0]), "yarray": np.array([100.0, 200.0]), "metadata": {"thing1": 1, "thing2": "thing2"}, From afe814b82d09e6bceeba64b3716aa10a2bae4ad8 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 13:46:16 -0500 Subject: [PATCH 14/31] Fix typo in docstrings --- src/diffpy/utils/diffraction_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index ed42ba83..6aa54682 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -63,7 +63,7 @@ class DiffractionObject: >>> from diffpy.utils.diffraction_objects import DiffractionObject ... >>> x = np.array([0.12, 0.24, 0.31, 0.4]) # independent variable (e.g., q) - >>> y = np.array([10, 20, 40, 60]) # intensity valuester + >>> y = np.array([10, 20, 40, 60]) # intensity values >>> metadata = { ... "package_info": {"version": "3.6.0"} ... } From 46c7be89e9cb53433bbf4b428dd16817a5be3f5a Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 13:56:07 -0500 Subject: [PATCH 15/31] Use refined param names for pytest parametrize --- tests/test_diffraction_objects.py | 154 ++++++++++++++++-------------- 1 file changed, 80 insertions(+), 74 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 9b6769b7..ecd5db16 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -370,67 +370,70 @@ def test_dump(tmp_path, mocker): assert actual == expected +test_init_valid_params = [ + ( # instantiate just array attributes + { + "xarray": np.array([0.0, 90.0, 180.0]), + "yarray": np.array([1.0, 2.0, 3.0]), + "xtype": "tth", + "wavelength": 4.0 * np.pi, + }, + { + "_all_arrays": np.array( + [ + [1.0, 0.0, 0.0, np.float64(np.inf)], + [2.0, 1.0 / np.sqrt(2), 90.0, np.sqrt(2) * 2 * np.pi], + [3.0, 1.0, 180.0, 1.0 * 2 * np.pi], + ] + ), + "metadata": {}, + "_input_xtype": "tth", + "name": "", + "scat_quantity": "", + "qmin": np.float64(0.0), + "qmax": np.float64(1.0), + "tthmin": np.float64(0.0), + "tthmax": np.float64(180.0), + "dmin": np.float64(2 * np.pi), + "dmax": np.float64(np.inf), + "wavelength": 4.0 * np.pi, + }, + ), + ( # instantiate just array attributes + { + "xarray": np.array([np.inf, 2 * np.sqrt(2) * np.pi, 2 * np.pi]), + "yarray": np.array([1.0, 2.0, 3.0]), + "xtype": "d", + "wavelength": 4.0 * np.pi, + "scat_quantity": "x-ray", + }, + { + "_all_arrays": np.array( + [ + [1.0, 0.0, 0.0, np.float64(np.inf)], + [2.0, 1.0 / np.sqrt(2), 90.0, np.sqrt(2) * 2 * np.pi], + [3.0, 1.0, 180.0, 1.0 * 2 * np.pi], + ] + ), + "metadata": {}, + "_input_xtype": "d", + "name": "", + "scat_quantity": "x-ray", + "qmin": np.float64(0.0), + "qmax": np.float64(1.0), + "tthmin": np.float64(0.0), + "tthmax": np.float64(180.0), + "dmin": np.float64(2 * np.pi), + "dmax": np.float64(np.inf), + "wavelength": 4.0 * np.pi, + }, + ), +] + + @pytest.mark.parametrize( "init_args, expected_do_dict", - [ - ( # instantiate just array attributes - { - "xarray": np.array([0.0, 90.0, 180.0]), - "yarray": np.array([1.0, 2.0, 3.0]), - "xtype": "tth", - "wavelength": 4.0 * np.pi, - }, - { - "_all_arrays": np.array( - [ - [1.0, 0.0, 0.0, np.float64(np.inf)], - [2.0, 1.0 / np.sqrt(2), 90.0, np.sqrt(2) * 2 * np.pi], - [3.0, 1.0, 180.0, 1.0 * 2 * np.pi], - ] - ), - "metadata": {}, - "_input_xtype": "tth", - "name": "", - "scat_quantity": "", - "qmin": np.float64(0.0), - "qmax": np.float64(1.0), - "tthmin": np.float64(0.0), - "tthmax": np.float64(180.0), - "dmin": np.float64(2 * np.pi), - "dmax": np.float64(np.inf), - "wavelength": 4.0 * np.pi, - }, - ), - ( # instantiate just array attributes - { - "xarray": np.array([np.inf, 2 * np.sqrt(2) * np.pi, 2 * np.pi]), - "yarray": np.array([1.0, 2.0, 3.0]), - "xtype": "d", - "wavelength": 4.0 * np.pi, - "scat_quantity": "x-ray", - }, - { - "_all_arrays": np.array( - [ - [1.0, 0.0, 0.0, np.float64(np.inf)], - [2.0, 1.0 / np.sqrt(2), 90.0, np.sqrt(2) * 2 * np.pi], - [3.0, 1.0, 180.0, 1.0 * 2 * np.pi], - ] - ), - "metadata": {}, - "_input_xtype": "d", - "name": "", - "scat_quantity": "x-ray", - "qmin": np.float64(0.0), - "qmax": np.float64(1.0), - "tthmin": np.float64(0.0), - "tthmax": np.float64(180.0), - "dmin": np.float64(2 * np.pi), - "dmax": np.float64(np.inf), - "wavelength": 4.0 * np.pi, - }, - ), - ], + test_init_valid_params, ) def test_init_valid(init_args, expected_do_dict): actual_do_dict = DiffractionObject(**init_args).__dict__ @@ -440,21 +443,24 @@ def test_init_valid(init_args, expected_do_dict): assert diff == {} -@pytest.mark.parametrize( - "init_args, error_message", - [ - ( # UC1: no arguments provided - {}, - "missing 3 required positional arguments: 'xarray', 'yarray', and 'xtype'", - ), - ( # UC2: only xarray and yarray provided - {"xarray": np.array([0.0, 90.0]), "yarray": np.array([0.0, 90.0])}, - "missing 1 required positional argument: 'xtype'", - ), - ], -) -def test_init_invalid_args(init_args, error_message): - with pytest.raises(TypeError, match=error_message): +test_init_invalid_params = [ + ( # UC1: no arguments provided + {}, + "missing 3 required positional arguments: 'xarray', 'yarray', and 'xtype'", + ), + ( # UC2: only xarray and yarray provided + {"xarray": np.array([0.0, 90.0]), "yarray": np.array([0.0, 90.0])}, + "missing 1 required positional argument: 'xtype'", + ), +] + + +@pytest.mark.parametrize("init_args, expected_error_msg", test_init_invalid_params) +def test_init_invalid_args( + init_args, + expected_error_msg, +): + with pytest.raises(TypeError, match=expected_error_msg): DiffractionObject(**init_args) From d24aacdb5ffea1778f4602f71fdd585f70babfac Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 13:58:25 -0500 Subject: [PATCH 16/31] Remove hard coded wavelength in test func --- tests/test_diffraction_objects.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index ecd5db16..992be091 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -85,7 +85,6 @@ { "scat_quantity": "x-ray", "xtype": "tth", - "wavelength": 0.71, "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, @@ -93,7 +92,6 @@ { "scat_quantity": "neutron", "xtype": "tth", - "wavelength": 0.71, "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, @@ -117,14 +115,12 @@ ( # Different metadata { "xtype": "q", - "wavelength": 0.71, "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 0, "thing2": "thing2"}, }, { "xtype": "q", - "wavelength": 0.71, "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, From e285214524534ee10c4335c9277edec5e45e9b8a Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 14:08:03 -0500 Subject: [PATCH 17/31] Add news for requires 3 input parameters of , , --- news/no-empty-object.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/no-empty-object.rst diff --git a/news/no-empty-object.rst b/news/no-empty-object.rst new file mode 100644 index 00000000..02126c98 --- /dev/null +++ b/news/no-empty-object.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* `DiffractionObject` requires 3 input parameters of `xarrays`, `yarrays`, `xtype` + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 7a2603e45d93ebf369535757ad0cc4eb0222328c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 15 Dec 2024 22:05:29 +0000 Subject: [PATCH 18/31] [pre-commit.ci] auto fixes from pre-commit hooks --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index cb33f760..0dd5024d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -38,8 +38,8 @@ def do_minimal(): # Create an instance of DiffractionObject with empty xarray and yarray values, and a non-empty wavelength return DiffractionObject(xarray=np.empty(0), yarray=np.empty(0), xtype="tth", wavelength=1.54) + @pytest.fixture def do_minimal_tth(): # Create an instance of DiffractionObject with non-empty xarray, yarray, and wavelength values return DiffractionObject(wavelength=2 * np.pi, xarray=np.array([30, 60]), yarray=np.array([1, 2]), xtype="tth") - From 8693153a019b43b9f55b5e1f5c41e1e63c326d50 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 21:12:41 -0500 Subject: [PATCH 19/31] Add metadata data by materials scientist --- src/diffpy/utils/diffraction_objects.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index 3d1653be..4caadd6a 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -65,7 +65,10 @@ class DiffractionObject: >>> x = np.array([0.12, 0.24, 0.31, 0.4]) # independent variable (e.g., q) >>> y = np.array([10, 20, 40, 60]) # intensity values >>> metadata = { - ... "package_info": {"version": "3.6.0"} + ... "sample": "rock salt from the beach", + ... "composition": "NaCl", + ... "temperature": "300 K,", + ... "experimenters": "Phill, Sally" ... } >>> do = DiffractionObject( ... xarray=x, @@ -95,7 +98,6 @@ def __init__( def _input_data(self, xarray, yarray, xtype, wavelength, scat_quantity, name, metadata): if xtype not in XQUANTITIES: raise ValueError(_xtype_wmsg(xtype)) - # Check xarray and yarray have the same length if len(xarray) != len(yarray): raise ValueError( @@ -103,7 +105,6 @@ def _input_data(self, xarray, yarray, xtype, wavelength, scat_quantity, name, me "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' " "with 'xarray' and 'yarray' of identical length." ) - self.scat_quantity = scat_quantity self.wavelength = wavelength self.metadata = metadata From e68b59e25ff66f3619b9fa14fdbbeec6e88ff928 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 21:15:55 -0500 Subject: [PATCH 20/31] Add name example to diffraction object example --- src/diffpy/utils/diffraction_objects.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index 4caadd6a..d28ef630 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -76,6 +76,7 @@ class DiffractionObject: ... xtype="q", ... wavelength=1.54, ... scat_quantity="x-ray", + ... name="Rock Salt X-ray Diffraction", ... metadata=metadata ... ) >>> print(do.metadata) From 235f624d0c24452cdd5ce5f3ba8915592504a52a Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 21:17:09 -0500 Subject: [PATCH 21/31] Order x, y, xtype for _set_arrays --- src/diffpy/utils/diffraction_objects.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index d28ef630..2ecc073f 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -111,7 +111,7 @@ def _input_data(self, xarray, yarray, xtype, wavelength, scat_quantity, name, me self.metadata = metadata self.name = name self._input_xtype = xtype - self._set_arrays(xarray, xtype, yarray) + self._set_arrays(xarray, yarray, xtype) self._set_min_max_xarray() def __eq__(self, other): @@ -295,7 +295,7 @@ def get_array_index(self, value, xtype=None): i = (np.abs(array - value)).argmin() return i - def _set_arrays(self, xarray, xtype, yarray): + def _set_arrays(self, xarray, yarray, xtype): self._all_arrays = np.empty(shape=(len(xarray), 4)) self._all_arrays[:, 0] = yarray if xtype.lower() in QQUANTITIES: From 88ea61b1550453cc0244f08a723f9fcd13ce41c8 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 21:20:38 -0500 Subject: [PATCH 22/31] Remove 0.71 harded coded wavelength --- tests/test_diffraction_objects.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 94345451..cfc86c63 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -49,7 +49,6 @@ ), ( # Different wavelengths { - "wavelength": 0.71, "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), @@ -66,7 +65,6 @@ ), ( # Different wavelengths { - "wavelength": 0.71, "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), From 6b20c1a2913d3f8b063838a74f78a4e498ffd240 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 21:24:10 -0500 Subject: [PATCH 23/31] Add wavelength of 0.711 and 0.71 back --- tests/test_diffraction_objects.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index cfc86c63..787d7be4 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -15,6 +15,7 @@ { "name": "same", "scat_quantity": "x-ray", + "wavelength": 0.71, "xtype": "q", "xarray": np.array([1.0, 2.0]), "yarray": np.array([100.0, 200.0]), @@ -23,6 +24,7 @@ { "name": "same", "scat_quantity": "x-ray", + "wavelength": 0.71, "xtype": "q", "xarray": np.array([1.0, 2.0]), "yarray": np.array([100.0, 200.0]), @@ -64,7 +66,8 @@ False, ), ( # Different wavelengths - { + { + "wavelength": 0.71, "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), From 9f0f11ac3a8e5713aa71984bcaf0091999422119 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 02:25:12 +0000 Subject: [PATCH 24/31] [pre-commit.ci] auto fixes from pre-commit hooks --- tests/test_diffraction_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 787d7be4..0dcc2163 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -66,7 +66,7 @@ False, ), ( # Different wavelengths - { + { "wavelength": 0.71, "xtype": "tth", "xarray": np.empty(0), From aa1af39567c0c24caa8195694a3c6f62a86bf2b9 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 21:28:00 -0500 Subject: [PATCH 25/31] Final setup of wavelenth value comparison --- tests/test_diffraction_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 0dcc2163..cb4e08ae 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -51,13 +51,13 @@ ), ( # Different wavelengths { + "wavelength": 0.71, "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), "metadata": {"thing1": 1, "thing2": "thing2"}, }, { - "wavelength": 0.42, "xtype": "tth", "xarray": np.empty(0), "yarray": np.empty(0), From d09d7fb38cd79666a5426a9dc934dce3a9955868 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Mon, 16 Dec 2024 05:36:28 -0500 Subject: [PATCH 26/31] news tweak --- news/no-empty-object.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/news/no-empty-object.rst b/news/no-empty-object.rst index 02126c98..7e4ec7a4 100644 --- a/news/no-empty-object.rst +++ b/news/no-empty-object.rst @@ -4,7 +4,7 @@ **Changed:** -* `DiffractionObject` requires 3 input parameters of `xarrays`, `yarrays`, `xtype` +* `DiffractionObject` requires 3 input parameters of `xarray`, `yarray`, `xtype`, to be instantiated. It can be instantiated with empty arrays. **Deprecated:** From 0e362c155b39eefbd7988f4f8bfec6696f97cd02 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Mon, 16 Dec 2024 05:41:39 -0500 Subject: [PATCH 27/31] tweak name example --- src/diffpy/utils/diffraction_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index 2ecc073f..a388f1b2 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -76,7 +76,7 @@ class DiffractionObject: ... xtype="q", ... wavelength=1.54, ... scat_quantity="x-ray", - ... name="Rock Salt X-ray Diffraction", + ... name="beach_rock_salt_1", ... metadata=metadata ... ) >>> print(do.metadata) From c1422402eb3695fd479fdd0cf5912d24ef1f913e Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Mon, 16 Dec 2024 05:45:56 -0500 Subject: [PATCH 28/31] tweak array length error message --- src/diffpy/utils/diffraction_objects.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index a388f1b2..ae61c094 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -99,12 +99,12 @@ def __init__( def _input_data(self, xarray, yarray, xtype, wavelength, scat_quantity, name, metadata): if xtype not in XQUANTITIES: raise ValueError(_xtype_wmsg(xtype)) - # Check xarray and yarray have the same length if len(xarray) != len(yarray): raise ValueError( - "'xarray' and 'yarray' must have the same length. " - "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' " - "with 'xarray' and 'yarray' of identical length." + "'xarray' and 'yarray' are different lengths. They must " + "correspond to each other and have the same length. " + "Please re-initialize 'DiffractionObject' + "with valid 'xarray' and 'yarray's" ) self.scat_quantity = scat_quantity self.wavelength = wavelength From 24b1bbcd832249ee23124f51aeb2f3c913181bd6 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Mon, 16 Dec 2024 05:53:08 -0500 Subject: [PATCH 29/31] fix missing quote --- src/diffpy/utils/diffraction_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index ae61c094..d72a2889 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -103,7 +103,7 @@ def _input_data(self, xarray, yarray, xtype, wavelength, scat_quantity, name, me raise ValueError( "'xarray' and 'yarray' are different lengths. They must " "correspond to each other and have the same length. " - "Please re-initialize 'DiffractionObject' + "Please re-initialize 'DiffractionObject'" "with valid 'xarray' and 'yarray's" ) self.scat_quantity = scat_quantity From 2c51af145f5d427594ebc51df4984e047b510b47 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Mon, 16 Dec 2024 06:01:29 -0500 Subject: [PATCH 30/31] fix error message check --- tests/test_diffraction_objects.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index cb4e08ae..0aa807e8 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -523,9 +523,9 @@ def test_id_setter_error(do_minimal): def test_xarray_yarray_length_mismatch(): with pytest.raises( ValueError, - match="'xarray' and 'yarray' must have the same length. " - "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' " - "with 'xarray' and 'yarray' of identical length", + match="'xarray' and 'yarray' are different lengths. " + "They must correspond to each other and have the same length. Please " + "re-initialize 'DiffractionObject'with valid 'xarray' and 'yarray's" ): DiffractionObject( xarray=np.array([1.0, 2.0]), yarray=np.array([0.0, 0.0, 0.0]), xtype="tth", wavelength=1.54 From ba4b985df971440325442a50ac6de63eaad05fa5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 11:03:49 +0000 Subject: [PATCH 31/31] [pre-commit.ci] auto fixes from pre-commit hooks --- tests/test_diffraction_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 0aa807e8..dfb67a3d 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -525,7 +525,7 @@ def test_xarray_yarray_length_mismatch(): ValueError, match="'xarray' and 'yarray' are different lengths. " "They must correspond to each other and have the same length. Please " - "re-initialize 'DiffractionObject'with valid 'xarray' and 'yarray's" + "re-initialize 'DiffractionObject'with valid 'xarray' and 'yarray's", ): DiffractionObject( xarray=np.array([1.0, 2.0]), yarray=np.array([0.0, 0.0, 0.0]), xtype="tth", wavelength=1.54