Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

191 adjust model and modelcollection to hold functionality from app #192

Merged
2 changes: 2 additions & 0 deletions src/easyreflectometry/data/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from .data_store import DataSet1D
from .data_store import ProjectData
from .measurement import load

__all__ = [
load,
ProjectData,
DataSet1D,
]
9 changes: 8 additions & 1 deletion src/easyreflectometry/data/data_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -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([])
Expand All @@ -92,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)
Expand Down Expand Up @@ -125,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))
3 changes: 3 additions & 0 deletions src/easyreflectometry/model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
):
Expand All @@ -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,
Expand Down Expand Up @@ -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,
}
}
Expand Down
27 changes: 14 additions & 13 deletions src/easyreflectometry/model/model_collection.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from __future__ import annotations

__author__ = 'github.com/arm61'

from typing import List
from typing import Optional
from typing import Tuple

from easyreflectometry.sample.collections.base_collection import BaseCollection
Expand Down Expand Up @@ -35,21 +34,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 index: Model to duplicate.
"""
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)
Expand All @@ -62,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
Expand Down
35 changes: 34 additions & 1 deletion src/easyreflectometry/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
from typing import Optional
from typing import Union

import numpy as np
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
Expand All @@ -18,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):
Expand Down Expand Up @@ -95,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)

Expand Down
32 changes: 29 additions & 3 deletions src/easyreflectometry/sample/assemblies/surfactant_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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 + '_MaterialTail',
interface=interface,
)
tail_layer = LayerAreaPerMolecule(
molecular_formula='C32D64',
thickness=16,
Expand All @@ -54,9 +64,17 @@ 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')
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,
Expand All @@ -65,8 +83,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,
Expand Down
26 changes: 26 additions & 0 deletions src/easyreflectometry/sample/collections/base_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
"""
Expand Down
22 changes: 22 additions & 0 deletions src/easyreflectometry/sample/collections/layer_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,25 @@ 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)
28 changes: 2 additions & 26 deletions src/easyreflectometry/sample/collections/material_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -57,28 +58,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)
17 changes: 8 additions & 9 deletions src/easyreflectometry/sample/collections/sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ 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',
interface=self.interface,
)
self._enable_changes_to_outermost_layers()
self.append(assembly)
self._disable_changes_to_outermost_layers()
Expand All @@ -78,26 +81,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):
Expand Down
Loading
Loading