From 847d6fcae21effa55bd62090a2870df51c484ace Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 3 Oct 2024 14:58:03 +0200 Subject: [PATCH 01/17] from materials collection to base collection --- .../model/model_collection.py | 24 +++-- .../sample/collections/base_collection.py | 26 ++++++ .../sample/collections/material_collection.py | 48 +++++----- .../collections/test_base_collection.py | 93 +++++++++++++++++++ .../collections/test_material_collection.py | 73 --------------- 5 files changed, 157 insertions(+), 107 deletions(-) diff --git a/src/easyreflectometry/model/model_collection.py b/src/easyreflectometry/model/model_collection.py index 79c50a37..b6323bf3 100644 --- a/src/easyreflectometry/model/model_collection.py +++ b/src/easyreflectometry/model/model_collection.py @@ -3,6 +3,7 @@ __author__ = 'github.com/arm61' from typing import List +from typing import Optional from typing import Tuple from easyreflectometry.sample.collections.base_collection import BaseCollection @@ -35,21 +36,24 @@ def __init__( super().__init__(name, interface, *models, **kwargs) - def add_model(self, new_model: Model): - """ - Add a model to the models. + def add_model(self, model: Optional[Model] = None): + """Add a model to the collection. - :param new_model: New model to be added. + :param model: Model to add. """ - self.append(new_model) + if model is None: + model = Model(name='Model new', interface=self.interface) + self.append(model) - def remove_model(self, index: int): - """ - Remove an model from the models. + def duplicate_model(self, index: int): + """Duplicate a model in the collection. - :param index: Index of the model to remove + :param model: Assembly to add. """ - self.pop(index) + to_be_duplicated = self[index] + duplicate = Model.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) + duplicate.name = duplicate.name + ' duplicate' + self.append(duplicate) def as_dict(self, skip: List[str] | None = None) -> dict: this_dict = super().as_dict(skip=skip) diff --git a/src/easyreflectometry/sample/collections/base_collection.py b/src/easyreflectometry/sample/collections/base_collection.py index 1c618226..851d1070 100644 --- a/src/easyreflectometry/sample/collections/base_collection.py +++ b/src/easyreflectometry/sample/collections/base_collection.py @@ -37,6 +37,32 @@ def names(self) -> list: """ return [i.name for i in self] + def move_up(self, index: int): + """Move the element at the given index up in the collection. + + :param index: Index of the element to move up. + """ + if index == 0: + return + self.insert(index - 1, self.pop(index)) + + def move_down(self, index: int): + """Move the element at the given index down in the collection. + + :param index: Index of the element to move down. + """ + if index == len(self) - 1: + return + self.insert(index + 1, self.pop(index)) + + def remove(self, index: int): + """ + Remove an element from the elements. + + :param index: Index of the element to remove + """ + self.pop(index) + @property def _dict_repr(self) -> dict: """ diff --git a/src/easyreflectometry/sample/collections/material_collection.py b/src/easyreflectometry/sample/collections/material_collection.py index 3e1a2690..dfa0b4f0 100644 --- a/src/easyreflectometry/sample/collections/material_collection.py +++ b/src/easyreflectometry/sample/collections/material_collection.py @@ -58,27 +58,27 @@ def duplicate_material(self, index: int): duplicate.name = duplicate.name + ' duplicate' self.append(duplicate) - def move_material_up(self, index: int): - """Move the material at the given index up in the collection. - - :param index: Index of the material to move up. - """ - if index == 0: - return - self.insert(index - 1, self.pop(index)) - - def move_material_down(self, index: int): - """Move the material at the given index down in the collection. - - :param index: Index of the material to move down. - """ - if index == len(self) - 1: - return - self.insert(index + 1, self.pop(index)) - - def remove_material(self, index: int): - """Remove the material at the given index from the collection. - - :param index: Index of the material to remove. - """ - self.pop(index) + # def move_material_up(self, index: int): + # """Move the material at the given index up in the collection. + + # :param index: Index of the material to move up. + # """ + # if index == 0: + # return + # self.insert(index - 1, self.pop(index)) + + # def move_material_down(self, index: int): + # """Move the material at the given index down in the collection. + + # :param index: Index of the material to move down. + # """ + # if index == len(self) - 1: + # return + # self.insert(index + 1, self.pop(index)) + + # def remove_material(self, index: int): + # """Remove the material at the given index from the collection. + + # :param index: Index of the material to remove. + # """ + # self.pop(index) diff --git a/tests/sample/collections/test_base_collection.py b/tests/sample/collections/test_base_collection.py index 78279009..e944a0a2 100644 --- a/tests/sample/collections/test_base_collection.py +++ b/tests/sample/collections/test_base_collection.py @@ -63,3 +63,96 @@ def test_as_dict(self): assert p.as_dict()['name'] == 'name' assert len(p.as_dict()['data']) == 1 assert p.as_dict()['data'][0]['name'] == 'layer' + + def test_move_up(self): + # When + elem_1 = Layer(name='layer_1') + elem_2 = Layer(name='layer_2') + elem_3 = Layer(name='layer_3') + mock_interface = MagicMock() + + p = BaseCollection('name', mock_interface, elem_1, elem_2, elem_3) + p.append(Layer(name='layer_4')) + + # Then + p.move_up(3) + + # Expect + assert p[2].name == 'layer_4' + assert p[3].name == 'layer_3' + + def test_move_up_to_top_and_further(self): + # When + elem_1 = Layer(name='layer_1') + elem_2 = Layer(name='layer_2') + elem_3 = Layer(name='layer_3') + mock_interface = MagicMock() + + p = BaseCollection('name', mock_interface, elem_1, elem_2, elem_3) + p.append(Layer(name='layer_4')) + + # Then + p.move_up(3) + p.move_up(2) + p.move_up(1) + p.move_up(0) + + # Then + assert p[0].name == 'layer_4' + assert p[3].name == 'layer_3' + + def test_move_down(self): + # When + elem_1 = Layer(name='layer_1') + elem_2 = Layer(name='layer_2') + elem_3 = Layer(name='layer_3') + mock_interface = MagicMock() + + p = BaseCollection('name', mock_interface, elem_1, elem_2, elem_3) + p.append(Layer(name='layer_4')) + + # Then + p.move_down(2) + + # Expect + assert p[2].name == 'layer_4' + assert p[3].name == 'layer_3' + + def test_move_down_to_bottom_and_further(self): + # When + elem_1 = Layer(name='layer_1') + elem_2 = Layer(name='layer_2') + elem_3 = Layer(name='layer_3') + mock_interface = MagicMock() + + p = BaseCollection('name', mock_interface, elem_1, elem_2, elem_3) + p.append(Layer(name='layer_4')) + p.append(Layer(name='layer_5')) + + # Then + p.move_down(3) + p.move_down(4) + + # Then + assert p[0].name == 'layer_1' + assert p[3].name == 'layer_5' + assert p[4].name == 'layer_4' + + def test_remove(self): + # When + elem_1 = Layer(name='layer_1') + elem_2 = Layer(name='layer_2') + elem_3 = Layer(name='layer_3') + mock_interface = MagicMock() + + p = BaseCollection('name', mock_interface, elem_1, elem_2, elem_3) + p.append(Layer(name='layer_4')) + + # Then + p.remove(1) + + # Then + assert len(p) == 3 + assert p[0].name == 'layer_1' + assert p[1].name == 'layer_3' + assert p[2].name == 'layer_4' diff --git a/tests/sample/collections/test_material_collection.py b/tests/sample/collections/test_material_collection.py index e25074fe..a1bdc6ef 100644 --- a/tests/sample/collections/test_material_collection.py +++ b/tests/sample/collections/test_material_collection.py @@ -96,76 +96,3 @@ def test_duplicate_material(self): # Then assert p[4].name == 'Boron duplicate' - - def test_move_material_up(self): - # Given - p = MaterialCollection() - k = Material(0.487, 0.000, 'Bottom') - p.add_material(k) - - # When - p.move_material_up(3) - - # Then - assert p[2].name == 'Bottom' - assert p[3].name == 'Si' - - def test_move_material_up_to_top_and_further(self): - # Given - p = MaterialCollection() - m = Material(0.487, 0.000, 'Bottom') - p.add_material(m) - - # When - p.move_material_up(3) - p.move_material_up(2) - p.move_material_up(1) - p.move_material_up(0) - - # Then - assert p[0].name == 'Bottom' - assert p[3].name == 'Si' - - def test_move_material_down(self): - # Given - p = MaterialCollection() - m = Material(0.487, 0.000, 'Bottom') - p.add_material(m) - - # When - p.move_material_down(2) - - # Then - assert p[2].name == 'Bottom' - assert p[3].name == 'Si' - - def test_move_material_down_to_bottom_and_further(self): - # Given - p = MaterialCollection() - k = Material(0.487, 0.000, 'Middle') - m = Material(0.487, 0.000, 'Bottom') - p.add_material(k) - p.add_material(m) - - # When - p.move_material_down(3) - p.move_material_down(4) - - # Then - assert p[0].name == 'Air' - assert p[3].name == 'Bottom' - assert p[4].name == 'Middle' - - def test_remove_material(self): - # Given - p = MaterialCollection() - m = Material(0.487, 0.000, 'Bottom') - p.add_material(m) - - # When - p.remove_material(1) - - # Then - assert len(p) == 3 - assert p[0].name == 'Air' - assert p[2].name == 'Bottom' From 73cb6e575f24e82ccd5fe65dbefb25e429df93f1 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 3 Oct 2024 15:09:23 +0200 Subject: [PATCH 02/17] added color to Model --- src/easyreflectometry/model/model.py | 3 +++ tests/model/test_model.py | 4 ++-- tests/model/test_model_collection.py | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/easyreflectometry/model/model.py b/src/easyreflectometry/model/model.py index 426706c1..2d24e88e 100644 --- a/src/easyreflectometry/model/model.py +++ b/src/easyreflectometry/model/model.py @@ -60,6 +60,7 @@ def __init__( background: Union[Parameter, Number, None] = None, resolution_function: Union[ResolutionFunction, None] = None, name: str = 'EasyModel', + color: str = 'black', unique_name: Optional[str] = None, interface=None, ): @@ -81,6 +82,7 @@ def __init__( scale = get_as_parameter('scale', scale, DEFAULTS) background = get_as_parameter('background', background, DEFAULTS) + self.color = color super().__init__( name=name, @@ -173,6 +175,7 @@ def _dict_repr(self) -> dict[str, dict[str, str]]: 'scale': float(self.scale.value), 'background': float(self.background.value), 'resolution': resolution, + 'color': self.color, 'sample': self.sample._dict_repr, } } diff --git a/tests/model/test_model.py b/tests/model/test_model.py index 97fd02a6..a86864d9 100644 --- a/tests/model/test_model.py +++ b/tests/model/test_model.py @@ -389,7 +389,7 @@ def test_repr(self): assert ( model.__repr__() - == 'EasyModel:\n scale: 1.0\n background: 1.0e-08\n resolution: 5.0 %\n sample:\n EasySample:\n - EasyMultilayer:\n EasyLayerCollection:\n - EasyLayer:\n material:\n EasyMaterial:\n sld: 4.186e-6 1/Å^2\n isld: 0.000e-6 1/Å^2\n thickness: 10.000 Å\n roughness: 3.300 Å\n - EasyMultilayer:\n EasyLayerCollection:\n - EasyLayer:\n material:\n EasyMaterial:\n sld: 4.186e-6 1/Å^2\n isld: 0.000e-6 1/Å^2\n thickness: 10.000 Å\n roughness: 3.300 Å\n' # noqa: E501 + == 'EasyModel:\n scale: 1.0\n background: 1.0e-08\n resolution: 5.0 %\n color: black\n sample:\n EasySample:\n - EasyMultilayer:\n EasyLayerCollection:\n - EasyLayer:\n material:\n EasyMaterial:\n sld: 4.186e-6 1/Å^2\n isld: 0.000e-6 1/Å^2\n thickness: 10.000 Å\n roughness: 3.300 Å\n - EasyMultilayer:\n EasyLayerCollection:\n - EasyLayer:\n material:\n EasyMaterial:\n sld: 4.186e-6 1/Å^2\n isld: 0.000e-6 1/Å^2\n thickness: 10.000 Å\n roughness: 3.300 Å\n' # noqa: E501 ) def test_repr_resolution_function(self): @@ -398,7 +398,7 @@ def test_repr_resolution_function(self): model.resolution_function = resolution_function assert ( model.__repr__() - == 'EasyModel:\n scale: 1.0\n background: 1.0e-08\n resolution: function of Q\n sample:\n EasySample:\n - EasyMultilayer:\n EasyLayerCollection:\n - EasyLayer:\n material:\n EasyMaterial:\n sld: 4.186e-6 1/Å^2\n isld: 0.000e-6 1/Å^2\n thickness: 10.000 Å\n roughness: 3.300 Å\n - EasyMultilayer:\n EasyLayerCollection:\n - EasyLayer:\n material:\n EasyMaterial:\n sld: 4.186e-6 1/Å^2\n isld: 0.000e-6 1/Å^2\n thickness: 10.000 Å\n roughness: 3.300 Å\n' # noqa: E501 + == 'EasyModel:\n scale: 1.0\n background: 1.0e-08\n resolution: function of Q\n color: black\n sample:\n EasySample:\n - EasyMultilayer:\n EasyLayerCollection:\n - EasyLayer:\n material:\n EasyMaterial:\n sld: 4.186e-6 1/Å^2\n isld: 0.000e-6 1/Å^2\n thickness: 10.000 Å\n roughness: 3.300 Å\n - EasyMultilayer:\n EasyLayerCollection:\n - EasyLayer:\n material:\n EasyMaterial:\n sld: 4.186e-6 1/Å^2\n isld: 0.000e-6 1/Å^2\n thickness: 10.000 Å\n roughness: 3.300 Å\n' # noqa: E501 ) diff --git a/tests/model/test_model_collection.py b/tests/model/test_model_collection.py index ebaa418a..f9974ead 100644 --- a/tests/model/test_model_collection.py +++ b/tests/model/test_model_collection.py @@ -59,7 +59,7 @@ def test_delete_model(self): # Then collection = ModelCollection(model_1, model_2) - collection.remove_model(0) + collection.remove(0) # Expect assert len(collection) == 1 From 9e0231f406e40fcc29a56108506d4da7e5b205ea Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Fri, 4 Oct 2024 07:11:26 +0200 Subject: [PATCH 03/17] renaming up and down to be consistent with other code --- .../sample/collections/sample.py | 12 ++++------- tests/sample/collections/test_sample.py | 20 +++++++++---------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/easyreflectometry/sample/collections/sample.py b/src/easyreflectometry/sample/collections/sample.py index ec9df191..228a244a 100644 --- a/src/easyreflectometry/sample/collections/sample.py +++ b/src/easyreflectometry/sample/collections/sample.py @@ -78,26 +78,22 @@ def duplicate_assembly(self, index: int): self.append(duplicate) self._disable_changes_to_outermost_layers() - def move_assembly_up(self, index: int): + def move_up(self, index: int): """Move the assembly at the given index up in the sample. :param index: Index of the assembly to move up. """ - if index == 0: - return self._enable_changes_to_outermost_layers() - self.insert(index - 1, self.pop(index)) + super().move_up(index) self._disable_changes_to_outermost_layers() - def move_assembly_down(self, index: int): + def move_down(self, index: int): """Move the assembly at the given index down in the sample. :param index: Index of the assembly to move down. """ - if index == len(self) - 1: - return self._enable_changes_to_outermost_layers() - self.insert(index + 1, self.pop(index)) + super().move_down(index) self._disable_changes_to_outermost_layers() def remove_assembly(self, index: int): diff --git a/tests/sample/collections/test_sample.py b/tests/sample/collections/test_sample.py index da4d2180..c515db18 100644 --- a/tests/sample/collections/test_sample.py +++ b/tests/sample/collections/test_sample.py @@ -123,7 +123,7 @@ def test_move_assembly_up(self): p._disable_changes_to_outermost_layers = MagicMock() # Then - p.move_assembly_up(2) + p.move_up(2) # Expect assert_equal(p[0].name, 'EasyMultilayer') @@ -141,14 +141,14 @@ def test_move_assembly_up_index_0(self): p._disable_changes_to_outermost_layers = MagicMock() # Then - p.move_assembly_up(0) + p.move_up(0) # Expect assert_equal(p[0].name, 'EasyMultilayer') assert_equal(p[1].name, 'EasyMultilayer') assert_equal(p[2].name, surfactant.name) - p._enable_changes_to_outermost_layers.assert_not_called() - p._disable_changes_to_outermost_layers.assert_not_called() + p._enable_changes_to_outermost_layers.assert_called() + p._disable_changes_to_outermost_layers.assert_called() def test_move_assembly_down(self): # When @@ -159,7 +159,7 @@ def test_move_assembly_down(self): p._disable_changes_to_outermost_layers = MagicMock() # Then - p.move_assembly_down(1) + p.move_down(1) # Expect assert_equal(p[0].name, 'EasyMultilayer') @@ -177,14 +177,14 @@ def test_move_assembly_down_index_2(self): p._disable_changes_to_outermost_layers = MagicMock() # Then - p.move_assembly_down(2) + p.move_down(2) # Expect assert_equal(p[0].name, 'EasyMultilayer') assert_equal(p[1].name, 'EasyMultilayer') assert_equal(p[2].name, surfactant.name) - p._enable_changes_to_outermost_layers.assert_not_called() - p._disable_changes_to_outermost_layers.assert_not_called() + p._enable_changes_to_outermost_layers.assert_called() + p._disable_changes_to_outermost_layers.assert_called() def test_remove_assembly(self): # When @@ -220,8 +220,8 @@ def test_superphase(self): p = Sample() layer = Multilayer(Layer(name='new layer')) p.add_assembly(layer) - p.move_assembly_up(2) - p.move_assembly_up(1) + p.move_up(2) + p.move_up(1) # Then layer = p.superphase From 83e22e7413f45c8a3f5704990c716d33ea134ed0 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Fri, 4 Oct 2024 08:39:16 +0200 Subject: [PATCH 04/17] adjusted collections --- .../sample/collections/layer_collection.py | 19 ++++++++++++++ .../sample/collections/material_collection.py | 25 ------------------- .../sample/elements/materials/material.py | 8 +++++- .../collections/test_layer_collection.py | 24 ++++++++++++++++++ .../collections/test_material_collection.py | 15 +++++------ tests/sample/collections/test_sample.py | 8 +++--- 6 files changed, 63 insertions(+), 36 deletions(-) diff --git a/src/easyreflectometry/sample/collections/layer_collection.py b/src/easyreflectometry/sample/collections/layer_collection.py index 2ddfabcc..c83918fc 100644 --- a/src/easyreflectometry/sample/collections/layer_collection.py +++ b/src/easyreflectometry/sample/collections/layer_collection.py @@ -20,3 +20,22 @@ def __init__( layers = [] super().__init__(name, interface, unique_name=unique_name, *layers, **kwargs) + + def add_layer(self, layer: Optional[Layer] = None): + """Add a layer to the collection. + + :param layer: Layer to add. + """ + if layer is None: + layer = Layer(name='New EasyLayer', interface=self.interface) + self.append(layer) + + def duplicate_layer(self, index: int): + """Duplicate a layer in the collection. + + :param layer: Assembly to add. + """ + to_be_duplicated = self[index] + duplicate = Layer.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) + duplicate.name = duplicate.name + ' duplicate' + self.append(duplicate) diff --git a/src/easyreflectometry/sample/collections/material_collection.py b/src/easyreflectometry/sample/collections/material_collection.py index dfa0b4f0..460e53f0 100644 --- a/src/easyreflectometry/sample/collections/material_collection.py +++ b/src/easyreflectometry/sample/collections/material_collection.py @@ -57,28 +57,3 @@ def duplicate_material(self, index: int): duplicate = Material.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) duplicate.name = duplicate.name + ' duplicate' self.append(duplicate) - - # def move_material_up(self, index: int): - # """Move the material at the given index up in the collection. - - # :param index: Index of the material to move up. - # """ - # if index == 0: - # return - # self.insert(index - 1, self.pop(index)) - - # def move_material_down(self, index: int): - # """Move the material at the given index down in the collection. - - # :param index: Index of the material to move down. - # """ - # if index == len(self) - 1: - # return - # self.insert(index + 1, self.pop(index)) - - # def remove_material(self, index: int): - # """Remove the material at the given index from the collection. - - # :param index: Index of the material to remove. - # """ - # self.pop(index) diff --git a/src/easyreflectometry/sample/elements/materials/material.py b/src/easyreflectometry/sample/elements/materials/material.py index 1485abaa..aadf2dfd 100644 --- a/src/easyreflectometry/sample/elements/materials/material.py +++ b/src/easyreflectometry/sample/elements/materials/material.py @@ -69,7 +69,13 @@ def __init__( unique_name_prefix=f'{unique_name}_Isld', ) - super().__init__(name=name, sld=sld, isld=isld, interface=interface) + super().__init__( + name=name, + sld=sld, + isld=isld, + interface=interface, + unique_name=unique_name, + ) # Representation @property diff --git a/tests/sample/collections/test_layer_collection.py b/tests/sample/collections/test_layer_collection.py index 2e17d3ab..2f457448 100644 --- a/tests/sample/collections/test_layer_collection.py +++ b/tests/sample/collections/test_layer_collection.py @@ -88,3 +88,27 @@ def test_dict_round_trip(self): # Expect assert sorted(r.as_data_dict()) == sorted(s.as_data_dict()) + + def test_add_layer(self): + # When + p = LayerCollection() + m = Layer(name='Layer m') + + # Then + p.add_layer() + p.add_layer(m) + + # Expect + assert p[1] == m + + def test_duplicate_layer(self): + # When + p = LayerCollection() + m = Layer(name='Layer m') + p.add_layer(m) + + # Then + p.duplicate_layer(0) + + # Expect + assert p[1].name == 'Layer m duplicate' diff --git a/tests/sample/collections/test_material_collection.py b/tests/sample/collections/test_material_collection.py index a1bdc6ef..514ef01f 100644 --- a/tests/sample/collections/test_material_collection.py +++ b/tests/sample/collections/test_material_collection.py @@ -75,24 +75,25 @@ def test_dict_round_trip(self): assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) def test_add_material(self): - # Given + # When p = MaterialCollection() m = Material(6.908, -0.278, 'Boron') - # When + # Then + p.add_material() p.add_material(m) - # Then - assert p[3] == m + # Expect + assert p[4] == m def test_duplicate_material(self): - # Given + # When p = MaterialCollection() m = Material(6.908, -0.278, 'Boron') p.add_material(m) - # When + # Then p.duplicate_material(3) - # Then + # Expect assert p[4].name == 'Boron duplicate' diff --git a/tests/sample/collections/test_sample.py b/tests/sample/collections/test_sample.py index c515db18..1cca441a 100644 --- a/tests/sample/collections/test_sample.py +++ b/tests/sample/collections/test_sample.py @@ -45,14 +45,16 @@ def test_add_assembly(self): surfactant = SurfactantLayer() # Then + p.add_assembly() p.add_assembly(surfactant) # Expect assert_equal(p[0].name, 'EasyMultilayer') assert_equal(p[1].name, 'EasyMultilayer') - assert_equal(p[2].name, 'EasySurfactantLayer') - p._enable_changes_to_outermost_layers.assert_called_once_with() - p._disable_changes_to_outermost_layers.assert_called_once_with() + assert_equal(p[2].name, 'New EasyMultilayer') + assert_equal(p[3].name, 'EasySurfactantLayer') + p._enable_changes_to_outermost_layers.assert_called() + p._disable_changes_to_outermost_layers.assert_called() # Problems with parameterized tests START def test_duplicate_assembly_multilayer(self): From 285472a376d6483af89078276118b251fe085393 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Wed, 9 Oct 2024 15:07:17 +0200 Subject: [PATCH 05/17] placeholder for calculated data --- src/easyreflectometry/project.py | 4 ++++ src/easyreflectometry/sample/collections/layer_collection.py | 3 ++- .../sample/collections/material_collection.py | 3 ++- src/easyreflectometry/sample/collections/sample.py | 3 ++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/easyreflectometry/project.py b/src/easyreflectometry/project.py index 018057cc..e3b02018 100644 --- a/src/easyreflectometry/project.py +++ b/src/easyreflectometry/project.py @@ -6,6 +6,7 @@ from typing import Optional from typing import Union +import numpy as np from easyscience import global_object from easyscience.fitting import AvailableMinimizers @@ -35,6 +36,9 @@ def __init__(self): self._created = False self._with_experiments = False + self._xArrays = [np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])] + self._yCalcArrays = [np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])] + def reset(self): del self._models del self._materials diff --git a/src/easyreflectometry/sample/collections/layer_collection.py b/src/easyreflectometry/sample/collections/layer_collection.py index c83918fc..df168a56 100644 --- a/src/easyreflectometry/sample/collections/layer_collection.py +++ b/src/easyreflectometry/sample/collections/layer_collection.py @@ -27,7 +27,8 @@ def add_layer(self, layer: Optional[Layer] = None): :param layer: Layer to add. """ if layer is None: - layer = Layer(name='New EasyLayer', interface=self.interface) + layer = Layer(name='New EasyLayer') + layer.interface = self.interface self.append(layer) def duplicate_layer(self, index: int): diff --git a/src/easyreflectometry/sample/collections/material_collection.py b/src/easyreflectometry/sample/collections/material_collection.py index 460e53f0..f4a42a10 100644 --- a/src/easyreflectometry/sample/collections/material_collection.py +++ b/src/easyreflectometry/sample/collections/material_collection.py @@ -45,7 +45,8 @@ def add_material(self, material: Optional[Material] = None): :param material: Material to add. """ if material is None: - material = Material(sld=2.074, isld=0.000, name='Si new', interface=self.interface) + material = Material(sld=2.074, isld=0.000, name='Si new') + material.interface = self.interface self.append(material) def duplicate_material(self, index: int): diff --git a/src/easyreflectometry/sample/collections/sample.py b/src/easyreflectometry/sample/collections/sample.py index 228a244a..0cc04768 100644 --- a/src/easyreflectometry/sample/collections/sample.py +++ b/src/easyreflectometry/sample/collections/sample.py @@ -56,7 +56,8 @@ def add_assembly(self, assembly: Optional[BaseAssembly] = None): :param assembly: Assembly to add. """ if assembly is None: - assembly = Multilayer(name='New EasyMultilayer', interface=self.interface) + assembly = Multilayer(name='New EasyMultilayer') + assembly.interface = self.interface self._enable_changes_to_outermost_layers() self.append(assembly) self._disable_changes_to_outermost_layers() From df8d366f1b6daf56f0a23134d15a13578401e36e Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 10 Oct 2024 06:50:31 +0200 Subject: [PATCH 06/17] ready to expose data --- src/easyreflectometry/data/__init__.py | 2 ++ src/easyreflectometry/project.py | 37 +++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/easyreflectometry/data/__init__.py b/src/easyreflectometry/data/__init__.py index 3676d427..fdecf1dd 100644 --- a/src/easyreflectometry/data/__init__.py +++ b/src/easyreflectometry/data/__init__.py @@ -1,7 +1,9 @@ +from .data_store import DataSet1D from .data_store import ProjectData from .measurement import load __all__ = [ load, ProjectData, + DataSet1D, ] diff --git a/src/easyreflectometry/project.py b/src/easyreflectometry/project.py index e3b02018..8b80988d 100644 --- a/src/easyreflectometry/project.py +++ b/src/easyreflectometry/project.py @@ -10,7 +10,7 @@ from easyscience import global_object from easyscience.fitting import AvailableMinimizers -from easyreflectometry.data.data_store import DataSet1D +from easyreflectometry.data import DataSet1D from easyreflectometry.model import Model from easyreflectometry.model import ModelCollection from easyreflectometry.sample import Layer @@ -19,6 +19,29 @@ from easyreflectometry.sample import Sample from easyreflectometry.sample.collections.base_collection import BaseCollection +MODELS_SAMPLE_DATA = [ + DataSet1D( + name='Sample Data 0', + x=np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + y=np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + ) +] +MODELS_MODEL_DATA = [ + DataSet1D( + name='Model Data 0', + x=np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + y=np.array([1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5]), + ) +] +EXPERIMENTAL_DATA = [ + DataSet1D( + name='Example Data 0', + x=np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + y=np.array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]), + ye=np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]), + ) +] + class Project: def __init__(self): @@ -36,9 +59,6 @@ def __init__(self): self._created = False self._with_experiments = False - self._xArrays = [np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])] - self._yCalcArrays = [np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])] - def reset(self): del self._models del self._materials @@ -99,6 +119,15 @@ def experiments(self, experiments: List[DataSet1D]) -> None: def path_json(self): return self.path / 'project.json' + def sample_data_for_model_at_index(self, index: int = 0) -> DataSet1D: + return MODELS_SAMPLE_DATA[index] + + def model_data_for_model_at_index(self, index: int = 0) -> DataSet1D: + return MODELS_MODEL_DATA[index] + + def experimental_data_for_model_at_index(self, index: int = 0) -> DataSet1D: + return EXPERIMENTAL_DATA[index] + def default_model(self): self._replace_collection(MaterialCollection(), self._materials) From c2d73b3789acf17e90d5530a65bb1b085aac06ab Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 10 Oct 2024 09:39:28 +0200 Subject: [PATCH 07/17] datastore and tests --- src/easyreflectometry/data/data_store.py | 3 ++- tests/model/test_model.py | 2 ++ tests/sample/assemblies/test_surfactant_layer.py | 9 +++++++++ .../elements/layers/test_layer_area_per_molecule.py | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/easyreflectometry/data/data_store.py b/src/easyreflectometry/data/data_store.py index 65965b8b..e473a96f 100644 --- a/src/easyreflectometry/data/data_store.py +++ b/src/easyreflectometry/data/data_store.py @@ -81,7 +81,8 @@ def __init__( y_label: str = 'y', ): self._model = model - self._model.background = np.min(y) + if y is not None and model is not None: + self._model.background = np.min(y) if x is None: x = np.array([]) diff --git a/tests/model/test_model.py b/tests/model/test_model.py index a86864d9..aee6a68c 100644 --- a/tests/model/test_model.py +++ b/tests/model/test_model.py @@ -407,6 +407,8 @@ def test_repr_resolution_function(self): [None, CalculatorFactory()], ) def test_dict_round_trip(interface): + global_object.map._clear() + # When resolution_function = LinearSpline([0, 10], [0, 10]) model = Model(interface=interface) diff --git a/tests/sample/assemblies/test_surfactant_layer.py b/tests/sample/assemblies/test_surfactant_layer.py index 85672708..3d2b3c5d 100644 --- a/tests/sample/assemblies/test_surfactant_layer.py +++ b/tests/sample/assemblies/test_surfactant_layer.py @@ -99,6 +99,9 @@ def test_constain_solvent_roughness(self): assert p.head_layer.roughness.value == 4 assert layer.roughness.value == 4 + # Seems to be needed to due to the constraint + global_object.map._clear() + def test_dict_repr(self): p = SurfactantLayer() assert p._dict_repr == { @@ -227,6 +230,9 @@ def test_dict_round_trip_area_per_molecule_constraint_enabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) + # Seems to be needed to due to the constraint + global_object.map._clear() + def test_dict_round_trip_area_per_molecule_constraint_disabled(): # When @@ -256,6 +262,9 @@ def test_dict_round_trip_roughness_constraint_enabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) + # Seems to be needed to due to the constraint + global_object.map._clear() + def test_dict_round_trip_roughness_constraint_disabled(): # When diff --git a/tests/sample/elements/layers/test_layer_area_per_molecule.py b/tests/sample/elements/layers/test_layer_area_per_molecule.py index acfabd9f..74c6d8cb 100644 --- a/tests/sample/elements/layers/test_layer_area_per_molecule.py +++ b/tests/sample/elements/layers/test_layer_area_per_molecule.py @@ -163,6 +163,8 @@ def test_dict_repr(self): } def test_dict_round_trip(self): + global_object.map._clear() + # When solvent = Material(-0.561, 0, 'H2O') p = LayerAreaPerMolecule( From 38ec4315c91c3926a2d50fe4ea907157ccff4611 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 10 Oct 2024 09:48:17 +0200 Subject: [PATCH 08/17] added functionality --- src/easyreflectometry/data/data_store.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/easyreflectometry/data/data_store.py b/src/easyreflectometry/data/data_store.py index e473a96f..3fc259f5 100644 --- a/src/easyreflectometry/data/data_store.py +++ b/src/easyreflectometry/data/data_store.py @@ -93,6 +93,9 @@ def __init__( if xe is None: xe = np.zeros_like(x) + if len(x) != len(y): + raise ValueError('x and y must be the same length') + self.name = name if not isinstance(x, np.ndarray): x = np.array(x) @@ -109,6 +112,10 @@ def __init__( self._color = None + @property + def data_points(self) -> int: + return zip(self.x, self.y) + @property def model(self) -> Model: return self._model From f277bf5fcf0f75e80b54397b67981565ee37658f Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 10 Oct 2024 10:09:20 +0200 Subject: [PATCH 09/17] code cleaning --- src/easyreflectometry/model/model_collection.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/easyreflectometry/model/model_collection.py b/src/easyreflectometry/model/model_collection.py index b6323bf3..041d14b8 100644 --- a/src/easyreflectometry/model/model_collection.py +++ b/src/easyreflectometry/model/model_collection.py @@ -1,7 +1,5 @@ from __future__ import annotations -__author__ = 'github.com/arm61' - from typing import List from typing import Optional from typing import Tuple @@ -48,7 +46,7 @@ def add_model(self, model: Optional[Model] = None): def duplicate_model(self, index: int): """Duplicate a model in the collection. - :param model: Assembly to add. + :param index: Model to duplicate. """ to_be_duplicated = self[index] duplicate = Model.from_dict(to_be_duplicated.as_dict(skip=['unique_name'])) @@ -66,7 +64,6 @@ def from_dict(cls, this_dict: dict) -> ModelCollection: Create an instance of a collection from a dictionary. :param data: The dictionary for the collection - :return: An instance of the collection """ collection_dict = this_dict.copy() # We neeed to call from_dict on the base class to get the models From c4fc32933decb2a79b35b93b5668213f9c49748f Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 10 Oct 2024 10:33:16 +0200 Subject: [PATCH 10/17] explicit clean global obejct for surfactant tests --- .../sample/assemblies/test_surfactant_layer.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/sample/assemblies/test_surfactant_layer.py b/tests/sample/assemblies/test_surfactant_layer.py index 3d2b3c5d..990f1982 100644 --- a/tests/sample/assemblies/test_surfactant_layer.py +++ b/tests/sample/assemblies/test_surfactant_layer.py @@ -189,6 +189,8 @@ def test_set_tail_layer(self): def test_dict_round_trip(): + global_object.map._clear() + # When solvent = Material(-0.561, 0, 'H2O') tail_layer = LayerAreaPerMolecule( @@ -216,8 +218,12 @@ def test_dict_round_trip(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) + global_object.map._clear() + def test_dict_round_trip_area_per_molecule_constraint_enabled(): + global_object.map._clear() + # When p = SurfactantLayer() p.constrain_area_per_molecule = True @@ -230,11 +236,12 @@ def test_dict_round_trip_area_per_molecule_constraint_enabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) - # Seems to be needed to due to the constraint global_object.map._clear() def test_dict_round_trip_area_per_molecule_constraint_disabled(): + global_object.map._clear() + # When p = SurfactantLayer() p.constrain_area_per_molecule = True @@ -248,8 +255,12 @@ def test_dict_round_trip_area_per_molecule_constraint_disabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) + global_object.map._clear() + def test_dict_round_trip_roughness_constraint_enabled(): + global_object.map._clear() + # When p = SurfactantLayer() p.conformal_roughness = True @@ -262,11 +273,12 @@ def test_dict_round_trip_roughness_constraint_enabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) - # Seems to be needed to due to the constraint global_object.map._clear() def test_dict_round_trip_roughness_constraint_disabled(): + global_object.map._clear() + # When p = SurfactantLayer() p.conformal_roughness = True @@ -279,3 +291,5 @@ def test_dict_round_trip_roughness_constraint_disabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) + + global_object.map._clear() From 1479d6c54d597a5982345429598c47a9a6eb3627 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 10 Oct 2024 11:47:48 +0200 Subject: [PATCH 11/17] unique name in surfactant and layer area per molecule --- .../sample/assemblies/surfactant_layer.py | 24 ++++++++++++++-- .../layers/layer_area_per_molecule.py | 17 +++++++---- .../assemblies/test_surfactant_layer.py | 28 +++++++++++-------- .../layers/test_layer_area_per_molecule.py | 2 +- 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/easyreflectometry/sample/assemblies/surfactant_layer.py b/src/easyreflectometry/sample/assemblies/surfactant_layer.py index 9c7d4144..dc1cb471 100644 --- a/src/easyreflectometry/sample/assemblies/surfactant_layer.py +++ b/src/easyreflectometry/sample/assemblies/surfactant_layer.py @@ -2,6 +2,7 @@ from typing import Optional +from easyscience import global_object from easyscience.Constraints import ObjConstraint from easyscience.Objects.new_variable import Parameter @@ -44,8 +45,17 @@ def __init__( :param conformal_roughness: Constrain the roughness to be the same for both layers, defaults to `False`. :param interface: Calculator interface, defaults to `None`. """ + if unique_name is None: + unique_name = global_object.generate_unique_name(self.__class__.__name__) + if tail_layer is None: - air = Material(0, 0, 'Air') + air = Material( + sld=0, + isld=0, + name='Air', + unique_name=unique_name + 'Material', + interface=interface, + ) tail_layer = LayerAreaPerMolecule( molecular_formula='C32D64', thickness=16, @@ -54,6 +64,8 @@ def __init__( area_per_molecule=48.2, roughness=3, name='DPPC Tail', + unique_name=unique_name + 'LayerAreaPerMoleculeTail', + interface=interface, ) if head_layer is None: d2o = Material(6.36, 0, 'D2O') @@ -65,8 +77,16 @@ def __init__( area_per_molecule=48.2, roughness=3.0, name='DPPC Head', + unique_name=unique_name + 'LayerAreaPerMoleculeHead', + interface=interface, ) - surfactant = LayerCollection(tail_layer, head_layer, name=name) + surfactant = LayerCollection( + tail_layer, + head_layer, + name='Layers', + unique_name=unique_name + 'LayerCollection', + interface=interface, + ) super().__init__( name=name, unique_name=unique_name, diff --git a/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py b/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py index 00737aa1..80fc465d 100644 --- a/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py +++ b/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py @@ -89,12 +89,18 @@ def __init__( :param name: Name of the layer, defaults to "EasyLayerAreaPerMolecule" :param interface: Interface object, defaults to `None` """ - if solvent is None: - solvent = Material(6.36, 0, 'D2O', interface=interface) - if unique_name is None: unique_name = global_object.generate_unique_name(self.__class__.__name__) + if solvent is None: + solvent = Material( + sld=6.36, + isld=0, + name='D2O', + unique_name=unique_name + 'MaterialSolvent', + ) + solvent.interface = interface + # Create the solvated molecule and corresponding constraints if molecular_formula is None: molecular_formula = DEFAULTS['molecular_formula'] @@ -102,8 +108,8 @@ def __init__( sld=0.0, isld=0.0, name=molecular_formula, + unique_name=unique_name + 'MaterialMolecule', interface=interface, - unique_name=unique_name + 'Material', ) thickness = get_as_parameter( @@ -155,14 +161,15 @@ def __init__( material=molecule_material, solvent=solvent, solvent_fraction=solvent_fraction, - interface=interface, unique_name=unique_name + 'MaterialSolvated', + interface=interface, ) super().__init__( material=solvated_molecule_material, thickness=thickness, roughness=roughness, name=name, + unique_name=unique_name, interface=interface, ) self._add_component('_scattering_length_real', _scattering_length_real) diff --git a/tests/sample/assemblies/test_surfactant_layer.py b/tests/sample/assemblies/test_surfactant_layer.py index 990f1982..ba4e06ff 100644 --- a/tests/sample/assemblies/test_surfactant_layer.py +++ b/tests/sample/assemblies/test_surfactant_layer.py @@ -100,7 +100,8 @@ def test_constain_solvent_roughness(self): assert layer.roughness.value == 4 # Seems to be needed to due to the constraint - global_object.map._clear() + + # global_object.map._clear() def test_dict_repr(self): p = SurfactantLayer() @@ -189,7 +190,7 @@ def test_set_tail_layer(self): def test_dict_round_trip(): - global_object.map._clear() + # global_object.map._clear() # When solvent = Material(-0.561, 0, 'H2O') @@ -218,11 +219,12 @@ def test_dict_round_trip(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) - global_object.map._clear() + +# global_object.map._clear() def test_dict_round_trip_area_per_molecule_constraint_enabled(): - global_object.map._clear() + # global_object.map._clear() # When p = SurfactantLayer() @@ -236,11 +238,12 @@ def test_dict_round_trip_area_per_molecule_constraint_enabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) - global_object.map._clear() + +# global_object.map._clear() def test_dict_round_trip_area_per_molecule_constraint_disabled(): - global_object.map._clear() + # global_object.map._clear() # When p = SurfactantLayer() @@ -255,11 +258,12 @@ def test_dict_round_trip_area_per_molecule_constraint_disabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) - global_object.map._clear() + +# global_object.map._clear() def test_dict_round_trip_roughness_constraint_enabled(): - global_object.map._clear() + # global_object.map._clear() # When p = SurfactantLayer() @@ -273,11 +277,12 @@ def test_dict_round_trip_roughness_constraint_enabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) - global_object.map._clear() + +# global_object.map._clear() def test_dict_round_trip_roughness_constraint_disabled(): - global_object.map._clear() + # global_object.map._clear() # When p = SurfactantLayer() @@ -292,4 +297,5 @@ def test_dict_round_trip_roughness_constraint_disabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) - global_object.map._clear() + +# global_object.map._clear() diff --git a/tests/sample/elements/layers/test_layer_area_per_molecule.py b/tests/sample/elements/layers/test_layer_area_per_molecule.py index 74c6d8cb..ad3e26da 100644 --- a/tests/sample/elements/layers/test_layer_area_per_molecule.py +++ b/tests/sample/elements/layers/test_layer_area_per_molecule.py @@ -163,7 +163,7 @@ def test_dict_repr(self): } def test_dict_round_trip(self): - global_object.map._clear() + # global_object.map._clear() # When solvent = Material(-0.561, 0, 'H2O') From ea5fd58d703ead8f18f1f12e6af7ecbbbe16a5c1 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 10 Oct 2024 12:46:34 +0200 Subject: [PATCH 12/17] code clean --- tests/model/test_model.py | 2 -- .../assemblies/test_surfactant_layer.py | 29 ------------------- 2 files changed, 31 deletions(-) diff --git a/tests/model/test_model.py b/tests/model/test_model.py index aee6a68c..a86864d9 100644 --- a/tests/model/test_model.py +++ b/tests/model/test_model.py @@ -407,8 +407,6 @@ def test_repr_resolution_function(self): [None, CalculatorFactory()], ) def test_dict_round_trip(interface): - global_object.map._clear() - # When resolution_function = LinearSpline([0, 10], [0, 10]) model = Model(interface=interface) diff --git a/tests/sample/assemblies/test_surfactant_layer.py b/tests/sample/assemblies/test_surfactant_layer.py index ba4e06ff..85672708 100644 --- a/tests/sample/assemblies/test_surfactant_layer.py +++ b/tests/sample/assemblies/test_surfactant_layer.py @@ -99,10 +99,6 @@ def test_constain_solvent_roughness(self): assert p.head_layer.roughness.value == 4 assert layer.roughness.value == 4 - # Seems to be needed to due to the constraint - - # global_object.map._clear() - def test_dict_repr(self): p = SurfactantLayer() assert p._dict_repr == { @@ -190,8 +186,6 @@ def test_set_tail_layer(self): def test_dict_round_trip(): - # global_object.map._clear() - # When solvent = Material(-0.561, 0, 'H2O') tail_layer = LayerAreaPerMolecule( @@ -220,12 +214,7 @@ def test_dict_round_trip(): assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) -# global_object.map._clear() - - def test_dict_round_trip_area_per_molecule_constraint_enabled(): - # global_object.map._clear() - # When p = SurfactantLayer() p.constrain_area_per_molecule = True @@ -239,12 +228,7 @@ def test_dict_round_trip_area_per_molecule_constraint_enabled(): assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) -# global_object.map._clear() - - def test_dict_round_trip_area_per_molecule_constraint_disabled(): - # global_object.map._clear() - # When p = SurfactantLayer() p.constrain_area_per_molecule = True @@ -259,12 +243,7 @@ def test_dict_round_trip_area_per_molecule_constraint_disabled(): assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) -# global_object.map._clear() - - def test_dict_round_trip_roughness_constraint_enabled(): - # global_object.map._clear() - # When p = SurfactantLayer() p.conformal_roughness = True @@ -278,12 +257,7 @@ def test_dict_round_trip_roughness_constraint_enabled(): assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) -# global_object.map._clear() - - def test_dict_round_trip_roughness_constraint_disabled(): - # global_object.map._clear() - # When p = SurfactantLayer() p.conformal_roughness = True @@ -296,6 +270,3 @@ def test_dict_round_trip_roughness_constraint_disabled(): # Expect assert sorted(p.as_data_dict()) == sorted(q.as_data_dict()) - - -# global_object.map._clear() From 74a356baf23876c27547abfeaac264ab21a3e949 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 10 Oct 2024 13:01:32 +0200 Subject: [PATCH 13/17] code cleaning --- .../sample/assemblies/surfactant_layer.py | 10 ++++++++-- .../sample/collections/layer_collection.py | 6 ++++-- .../sample/elements/layers/layer_area_per_molecule.py | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/easyreflectometry/sample/assemblies/surfactant_layer.py b/src/easyreflectometry/sample/assemblies/surfactant_layer.py index dc1cb471..e7ead885 100644 --- a/src/easyreflectometry/sample/assemblies/surfactant_layer.py +++ b/src/easyreflectometry/sample/assemblies/surfactant_layer.py @@ -53,7 +53,7 @@ def __init__( sld=0, isld=0, name='Air', - unique_name=unique_name + 'Material', + unique_name=unique_name + 'MaterialTail', interface=interface, ) tail_layer = LayerAreaPerMolecule( @@ -68,7 +68,13 @@ def __init__( interface=interface, ) if head_layer is None: - d2o = Material(6.36, 0, 'D2O') + d2o = Material( + sld=6.36, + isld=0, + name='D2O', + unique_name=unique_name + 'MaterialHead', + interface=interface, + ) head_layer = LayerAreaPerMolecule( molecular_formula='C10H18NO8P', thickness=10.0, diff --git a/src/easyreflectometry/sample/collections/layer_collection.py b/src/easyreflectometry/sample/collections/layer_collection.py index df168a56..d3080ab2 100644 --- a/src/easyreflectometry/sample/collections/layer_collection.py +++ b/src/easyreflectometry/sample/collections/layer_collection.py @@ -27,8 +27,10 @@ def add_layer(self, layer: Optional[Layer] = None): :param layer: Layer to add. """ if layer is None: - layer = Layer(name='New EasyLayer') - layer.interface = self.interface + layer = Layer( + name='New EasyLayer', + interface=self.interface, + ) self.append(layer) def duplicate_layer(self, index: int): diff --git a/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py b/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py index 80fc465d..ff0016a2 100644 --- a/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py +++ b/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py @@ -98,8 +98,8 @@ def __init__( isld=0, name='D2O', unique_name=unique_name + 'MaterialSolvent', + interface=interface, ) - solvent.interface = interface # Create the solvated molecule and corresponding constraints if molecular_formula is None: From 8fa68ea72544d4d4131607cd060a1a6852fe767c Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 10 Oct 2024 13:04:04 +0200 Subject: [PATCH 14/17] code cleaning --- src/easyreflectometry/sample/collections/sample.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/easyreflectometry/sample/collections/sample.py b/src/easyreflectometry/sample/collections/sample.py index 0cc04768..c763c240 100644 --- a/src/easyreflectometry/sample/collections/sample.py +++ b/src/easyreflectometry/sample/collections/sample.py @@ -56,8 +56,10 @@ def add_assembly(self, assembly: Optional[BaseAssembly] = None): :param assembly: Assembly to add. """ if assembly is None: - assembly = Multilayer(name='New EasyMultilayer') - assembly.interface = self.interface + assembly = Multilayer( + name='New EasyMultilayer', + interface=self.interface, + ) self._enable_changes_to_outermost_layers() self.append(assembly) self._disable_changes_to_outermost_layers() From 33c30d4c9d5d7cd752ccfd42ffbdbad4eb1991c7 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Fri, 11 Oct 2024 10:36:56 +0200 Subject: [PATCH 15/17] pr response --- tests/sample/collections/test_base_collection.py | 8 ++++++++ .../elements/layers/test_layer_area_per_molecule.py | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/sample/collections/test_base_collection.py b/tests/sample/collections/test_base_collection.py index e944a0a2..b9ad429e 100644 --- a/tests/sample/collections/test_base_collection.py +++ b/tests/sample/collections/test_base_collection.py @@ -78,6 +78,8 @@ def test_move_up(self): p.move_up(3) # Expect + assert p[0].name == 'layer_1' + assert p[1].name == 'layer_2' assert p[2].name == 'layer_4' assert p[3].name == 'layer_3' @@ -99,6 +101,8 @@ def test_move_up_to_top_and_further(self): # Then assert p[0].name == 'layer_4' + assert p[1].name == 'layer_1' + assert p[2].name == 'layer_2' assert p[3].name == 'layer_3' def test_move_down(self): @@ -115,6 +119,8 @@ def test_move_down(self): p.move_down(2) # Expect + assert p[0].name == 'layer_1' + assert p[1].name == 'layer_2' assert p[2].name == 'layer_4' assert p[3].name == 'layer_3' @@ -135,6 +141,8 @@ def test_move_down_to_bottom_and_further(self): # Then assert p[0].name == 'layer_1' + assert p[1].name == 'layer_2' + assert p[2].name == 'layer_3' assert p[3].name == 'layer_5' assert p[4].name == 'layer_4' diff --git a/tests/sample/elements/layers/test_layer_area_per_molecule.py b/tests/sample/elements/layers/test_layer_area_per_molecule.py index ad3e26da..acfabd9f 100644 --- a/tests/sample/elements/layers/test_layer_area_per_molecule.py +++ b/tests/sample/elements/layers/test_layer_area_per_molecule.py @@ -163,8 +163,6 @@ def test_dict_repr(self): } def test_dict_round_trip(self): - # global_object.map._clear() - # When solvent = Material(-0.561, 0, 'H2O') p = LayerAreaPerMolecule( From b006b5d1f4b660c739a24a34d5d535900492c3b9 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Fri, 11 Oct 2024 11:21:56 +0200 Subject: [PATCH 16/17] pr response and tests --- src/easyreflectometry/data/data_store.py | 7 ++-- tests/data/test_data_store.py | 44 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 tests/data/test_data_store.py diff --git a/src/easyreflectometry/data/data_store.py b/src/easyreflectometry/data/data_store.py index 3fc259f5..aec66e57 100644 --- a/src/easyreflectometry/data/data_store.py +++ b/src/easyreflectometry/data/data_store.py @@ -112,10 +112,6 @@ def __init__( self._color = None - @property - def data_points(self) -> int: - return zip(self.x, self.y) - @property def model(self) -> Model: return self._model @@ -133,5 +129,8 @@ def is_experiment(self) -> bool: def is_simulation(self) -> bool: return self._model is None + def data_points(self) -> int: + return zip(self.x, self.y) + def __repr__(self) -> str: return "1D DataStore of '{:s}' Vs '{:s}' with {} data points".format(self.x_label, self.y_label, len(self.x)) diff --git a/tests/data/test_data_store.py b/tests/data/test_data_store.py new file mode 100644 index 00000000..78d080da --- /dev/null +++ b/tests/data/test_data_store.py @@ -0,0 +1,44 @@ +from numpy.testing import assert_almost_equal + +from easyreflectometry.data.data_store import DataSet1D + + +class TestDataStore: + def test_constructor(self): + # When + data = DataSet1D( + x=[1, 2, 3], y=[4, 5, 6], ye=[7, 8, 9], xe=[10, 11, 12], x_label='label_x', y_label='label_y', name='MyDataSet1D' + ) + + # Then Expect + assert data.name == 'MyDataSet1D' + assert_almost_equal(data.x, [1, 2, 3]) + assert data.x_label == 'label_x' + assert_almost_equal(data.xe, [10, 11, 12]) + assert_almost_equal(data.y, [4, 5, 6]) + assert data.y_label == 'label_y' + assert_almost_equal(data.ye, [7, 8, 9]) + + def test_repr(self): + # When + data = DataSet1D( + x=[1, 2, 3], y=[4, 5, 6], ye=[7, 8, 9], xe=[10, 11, 12], x_label='label_x', y_label='label_y', name='MyDataSet1D' + ) + + # Then + repr = str(data) + + # Expect + assert repr == r"1D DataStore of 'label_x' Vs 'label_y' with 3 data points" + + def test_data_points(self): + # When + data = DataSet1D( + x=[1, 2, 3], y=[4, 5, 6], ye=[7, 8, 9], xe=[10, 11, 12], x_label='label_x', y_label='label_y', name='MyDataSet1D' + ) + + # Then + points = data.data_points() + + # Expect + assert list(points) == [(1, 4), (2, 5), (3, 6)] From 79e54e7d558e3e089bc1bb4aa36d0bf4ac647702 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Fri, 11 Oct 2024 11:30:19 +0200 Subject: [PATCH 17/17] pr response --- .../sample/assemblies/surfactant_layer.py | 10 +++++----- .../sample/elements/layers/layer_area_per_molecule.py | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/easyreflectometry/sample/assemblies/surfactant_layer.py b/src/easyreflectometry/sample/assemblies/surfactant_layer.py index e7ead885..6f892a69 100644 --- a/src/easyreflectometry/sample/assemblies/surfactant_layer.py +++ b/src/easyreflectometry/sample/assemblies/surfactant_layer.py @@ -53,7 +53,7 @@ def __init__( sld=0, isld=0, name='Air', - unique_name=unique_name + 'MaterialTail', + unique_name=unique_name + '_MaterialTail', interface=interface, ) tail_layer = LayerAreaPerMolecule( @@ -64,7 +64,7 @@ def __init__( area_per_molecule=48.2, roughness=3, name='DPPC Tail', - unique_name=unique_name + 'LayerAreaPerMoleculeTail', + unique_name=unique_name + '_LayerAreaPerMoleculeTail', interface=interface, ) if head_layer is None: @@ -72,7 +72,7 @@ def __init__( sld=6.36, isld=0, name='D2O', - unique_name=unique_name + 'MaterialHead', + unique_name=unique_name + '_MaterialHead', interface=interface, ) head_layer = LayerAreaPerMolecule( @@ -83,14 +83,14 @@ def __init__( area_per_molecule=48.2, roughness=3.0, name='DPPC Head', - unique_name=unique_name + 'LayerAreaPerMoleculeHead', + unique_name=unique_name + '_LayerAreaPerMoleculeHead', interface=interface, ) surfactant = LayerCollection( tail_layer, head_layer, name='Layers', - unique_name=unique_name + 'LayerCollection', + unique_name=unique_name + '_LayerCollection', interface=interface, ) super().__init__( diff --git a/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py b/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py index ff0016a2..326fbb9e 100644 --- a/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py +++ b/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py @@ -97,7 +97,7 @@ def __init__( sld=6.36, isld=0, name='D2O', - unique_name=unique_name + 'MaterialSolvent', + unique_name=unique_name + '_MaterialSolvent', interface=interface, ) @@ -108,7 +108,7 @@ def __init__( sld=0.0, isld=0.0, name=molecular_formula, - unique_name=unique_name + 'MaterialMolecule', + unique_name=unique_name + '_MaterialMolecule', interface=interface, ) @@ -161,7 +161,7 @@ def __init__( material=molecule_material, solvent=solvent, solvent_fraction=solvent_fraction, - unique_name=unique_name + 'MaterialSolvated', + unique_name=unique_name + '_MaterialSolvated', interface=interface, ) super().__init__(