Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
bb7bcfd
initial commit
rozyczko May 9, 2025
c8f70d1
ruff
rozyczko May 9, 2025
ddc90a6
fixed unit tests
rozyczko May 9, 2025
ade4d9a
updated smearing
rozyczko May 23, 2025
e93b0f3
fix unit tests
rozyczko May 26, 2025
876a5e4
ruff fix for tests
rozyczko May 26, 2025
5d110a0
updated/fixed pointwise impl
rozyczko Jul 23, 2025
5e75971
Merge branch 'develop' into pointwise_resolution
rozyczko Jul 23, 2025
c796258
ruff on tests
rozyczko Jul 23, 2025
c1d9682
fix method name
rozyczko Jul 29, 2025
13cb7c5
datasets now have proper names, instead of `R_0` and `Qz_0`.
rozyczko Jul 31, 2025
c813ada
added color changer, renamed default model, minor fixes
rozyczko Aug 7, 2025
a4a1b9d
fix ruff, fix test name
rozyczko Aug 8, 2025
0dc62dc
added experiment index
rozyczko Aug 8, 2025
86219e6
added tests
rozyczko Aug 8, 2025
aed1629
fix issue with multiple experiments and a single model
rozyczko Aug 15, 2025
c73638b
added a helper method
rozyczko Aug 19, 2025
f9f0705
Merge branch 'pointwise_resolution' of https://github.com/EasyScience…
rozyczko Aug 19, 2025
1d7b138
initial version. Much to be done
rozyczko Sep 2, 2025
4caf435
some more conversions
rozyczko Sep 2, 2025
4574620
constraint fixes
rozyczko Sep 9, 2025
99034b9
Merge branch 'new_easycore' of https://github.com/easyscience/EasyRef…
rozyczko Sep 9, 2025
3c776b2
ruff
rozyczko Sep 9, 2025
b58d58c
proper module name
rozyczko Sep 10, 2025
a21d8f9
added state variable
rozyczko Sep 10, 2025
b21981c
ruff on tests
rozyczko Sep 11, 2025
73adc44
fixes
rozyczko Sep 11, 2025
9ff8899
skip a trouble test
rozyczko Sep 11, 2025
119f6bd
update python versioning
rozyczko Sep 12, 2025
14837bd
Merge branch 'develop' into new_easycore
rozyczko Sep 15, 2025
b62c3eb
ruff formatting
rozyczko Sep 15, 2025
a84c150
case_fixes have been merged to develop
rozyczko Sep 19, 2025
334c63c
update dependencies. Unpin everything but refl1d
rozyczko Sep 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/documentation-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.10.12
python-version: 3.11
- name: Install Pandoc, repo and dependencies
run: |
sudo apt install pandoc
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ['3.10', '3.11', '3.12']
python-version: ['3.11', '3.12']
os: [ubuntu-latest, macos-latest, windows-latest]

runs-on: ${{ matrix.os }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11','3.12']
python-version: ['3.11','3.12']
if: "!contains(github.event.head_commit.message, '[ci skip]')"

steps:
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Before you submit a pull request, check that it meets these guidelines:
2. If the pull request adds functionality, the docs should be updated. Put
your new functionality into a function with a docstring, and add the
feature to the list in README.md.
3. The pull request should work for Python, 3.10, 3.11 and 3.12, and for PyPy. Check
3. The pull request should work for Python, 3.11 and 3.12, and for PyPy. Check
https://travis-ci.com/easyScience/EasyReflectometryLib/pull_requests
and make sure that the tests pass for all supported Python versions.

Expand Down
48 changes: 23 additions & 25 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,40 @@ classifiers = [
"Topic :: Scientific/Engineering",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Development Status :: 3 - Alpha"
]

requires-python = ">=3.10,<3.13"
requires-python = ">=3.11,<3.13"

dependencies = [
"easyscience==1.3.0",
"scipp==25.2.0",
"refnx==0.1.52",
"easyscience",
"scipp",
"refnx",
"refl1d[webview]==1.0.0a12",
"orsopy==1.2.1",
"xhtml2pdf==0.2.17",
"bumps==1.0.0b7",
"orsopy",
"xhtml2pdf",
"bumps",
]

[project.optional-dependencies]
dev = [
"build==1.2.2.post1",
"codecov==2.1.13",
"coverage==7.7.0",
"coveralls==4.0.1",
"flake8==7.1.2",
"ipykernel==6.29.5",
"jupyter==1.1.1",
"jupyterlab==4.3.6",
"plopp==25.3.0",
"pooch==1.8.2",
"pytest==8.3.5",
"pytest-cov==6.0.0",
"ruff==0.11.0",
"toml==0.10.2",
"yapf==0.43.0",
"build",
"codecov",
"coverage",
"coveralls",
"flake8",
"ipykernel",
"jupyter",
"jupyterlab",
"plopp",
"pooch",
"pytest",
"pytest-cov",
"ruff",
"toml",
"yapf",
]

docs = [
Expand Down Expand Up @@ -134,10 +133,9 @@ force-single-line = true
legacy_tox_ini = """
[tox]
isolated_build = True
envlist = py{3.10,3.11,3.12}
envlist = py{3.11,3.12}
[gh-actions]
python =
3.10: py310
3.11: py311
3.12: py312
[gh-actions:env]
Expand Down
2 changes: 1 addition & 1 deletion src/easyreflectometry/calculators/bornagain/calculator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__author__ = 'github.com/arm61'

from easyscience.Objects.Inferface import ItemContainer
from easyscience.fitting.calculators.interface_factory import ItemContainer

from easyreflectometry.model import Model
from easyreflectometry.sample import Layer
Expand Down
6 changes: 3 additions & 3 deletions src/easyreflectometry/calculators/calculator_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from typing import Callable

import numpy as np
from easyscience.Objects.core import ComponentSerializer
from easyscience.Objects.Inferface import ItemContainer
from easyscience.fitting.calculators.interface_factory import ItemContainer
from easyscience.io import SerializerComponent

from easyreflectometry.model import Model
from easyreflectometry.sample import BaseAssembly
Expand All @@ -17,7 +17,7 @@
from .wrapper_base import WrapperBase


class CalculatorBase(ComponentSerializer, metaclass=ABCMeta):
class CalculatorBase(SerializerComponent, metaclass=ABCMeta):
"""
This class is a template and defines all properties that a calculator should have.
"""
Expand Down
2 changes: 1 addition & 1 deletion src/easyreflectometry/calculators/factory.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
__author__ = 'github.com/wardsimon'
from typing import Callable

from easyscience.Objects.Inferface import InterfaceFactoryTemplate
from easyscience.fitting.calculators.interface_factory import InterfaceFactoryTemplate

from easyreflectometry.calculators import CalculatorBase

Expand Down
8 changes: 4 additions & 4 deletions src/easyreflectometry/calculators/refl1d/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ def create_item(self, name: str):

:param name: The name of the item
"""
self.storage['item'][name] = Repeat(
names.Stack(names.Slab(names.SLD(), thickness=0, interface=0)), name=str(name)
)
self.storage['item'][name] = Repeat(names.Stack(names.Slab(names.SLD(), thickness=0, interface=0)), name=str(name))
del self.storage['item'][name].stack[0]

def update_layer(self, name: str, **kwargs):
Expand All @@ -66,7 +64,9 @@ def get_layer_value(self, name: str, key: str) -> float:
:param key: The given value keys
"""
if key in ['magnetism_rhoM', 'magnetism_thetaM']:
return getattr(self.storage['layer'][name].magnetism, key.split('_')[-1]).value #TODO: check if we want to return the raw value or the full Parameter # noqa: E501
return getattr(
self.storage['layer'][name].magnetism, key.split('_')[-1]
).value # TODO: check if we want to return the raw value or the full Parameter # noqa: E501
return super().get_layer_value(name, key)

def create_model(self, name: str):
Expand Down
10 changes: 5 additions & 5 deletions src/easyreflectometry/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from .measurement import merge_datagroups

__all__ = [
"load",
"load_as_dataset",
"merge_datagroups",
"ProjectData",
"DataSet1D",
'load',
'load_as_dataset',
'merge_datagroups',
'ProjectData',
'DataSet1D',
]
13 changes: 7 additions & 6 deletions src/easyreflectometry/data/data_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
from typing import Union

import numpy as np
from easyscience.Objects.core import ComponentSerializer
from easyscience.Utils.io.dict import DictSerializer
from easyscience.io import SerializerComponent
from easyscience.io import SerializerDict

# from easyscience.utils.io.dict import DictSerializer
from easyreflectometry.model import Model

T = TypeVar('T')


class ProjectData(ComponentSerializer):
class ProjectData(SerializerComponent):
def __init__(self, name='DataStore', exp_data=None, sim_data=None):
self.name = name
if exp_data is None:
Expand All @@ -25,7 +26,7 @@ def __init__(self, name='DataStore', exp_data=None, sim_data=None):
self.sim_data = sim_data


class DataStore(Sequence, ComponentSerializer):
class DataStore(Sequence, SerializerComponent):
def __init__(self, *args, name='DataStore'):
self.name = name
self.items = list(args)
Expand Down Expand Up @@ -55,7 +56,7 @@ def from_dict(cls, d):
items = d['items']
del d['items']
obj = cls.from_dict(d)
decoder = DictSerializer()
decoder = SerializerDict()
obj.items = [decoder.decode(item) for item in items]
return obj

Expand All @@ -68,7 +69,7 @@ def simulations(self):
return [self[idx] for idx in range(len(self)) if self[idx].is_simulation]


class DataSet1D(ComponentSerializer):
class DataSet1D(SerializerComponent):
def __init__(
self,
name: str = 'Series',
Expand Down
5 changes: 3 additions & 2 deletions src/easyreflectometry/data/measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def _load_txt(fname: Union[TextIO, str]) -> sc.DataGroup:

# Verify minimum column requirement
if num_columns < 3:
raise ValueError(f"File must contain at least 3 columns (found {num_columns})")
raise ValueError(f'File must contain at least 3 columns (found {num_columns})')

# Now unpack the data based on column count
if num_columns >= 4:
Expand All @@ -116,7 +116,7 @@ def _load_txt(fname: Union[TextIO, str]) -> sc.DataGroup:

except (ValueError, IOError) as error:
# Re-raise with more descriptive message
raise ValueError(f"Failed to load data from {fname}: {str(error)}") from error
raise ValueError(f'Failed to load data from {fname}: {str(error)}') from error

data_name = 'R_' + basename
coords_name = 'Qz_' + basename
Expand All @@ -131,6 +131,7 @@ def _load_txt(fname: Union[TextIO, str]) -> sc.DataGroup:
}
return sc.DataGroup(data=data, coords=coords)


def merge_datagroups(*data_groups: sc.DataGroup) -> sc.DataGroup:
"""Merge multiple DataGroups into a single DataGroup."""
merged_data = {}
Expand Down
12 changes: 6 additions & 6 deletions src/easyreflectometry/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from .resolution_functions import ResolutionFunction

__all__ = (
"LinearSpline",
"PercentageFwhm",
"Pointwise",
"ResolutionFunction",
"Model",
"ModelCollection",
'LinearSpline',
'PercentageFwhm',
'Pointwise',
'ResolutionFunction',
'Model',
'ModelCollection',
)
7 changes: 4 additions & 3 deletions src/easyreflectometry/model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
from typing import Union

import numpy as np
from easyscience import ObjBase as BaseObj
from easyscience import global_object
from easyscience.Objects.ObjectClasses import BaseObj
from easyscience.Objects.variable import Parameter
from easyscience.variable import Parameter

from easyreflectometry.sample import BaseAssembly
from easyreflectometry.sample import Sample
Expand Down Expand Up @@ -42,7 +42,8 @@
},
}

COLORS =["#0173B2", "#DE8F05", "#029E73", "#D55E00", "#CC78BC", "#CA9161", "#FBAFE4", "#949494", "#ECE133", "#56B4E9"]
COLORS = ['#0173B2', '#DE8F05', '#029E73', '#D55E00', '#CC78BC', '#CA9161', '#FBAFE4', '#949494', '#ECE133', '#56B4E9']


class Model(BaseObj):
"""Model is the class that represents the experiment.
Expand Down
2 changes: 1 addition & 1 deletion src/easyreflectometry/model/model_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ def from_dict(cls, this_dict: dict) -> ModelCollection:
collection.add_model(Model.from_dict(model_data))

if len(collection) != len(this_dict['data']):
raise ValueError(f"Expected {len(collection)} models, got {len(this_dict['data'])}")
raise ValueError(f'Expected {len(collection)} models, got {len(this_dict["data"])}')

return collection
15 changes: 8 additions & 7 deletions src/easyreflectometry/model/resolution_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ def as_dict(
) -> dict[str, str]: # skip is kept for consistency of the as_dict signature
return {'smearing': 'LinearSpline', 'q_data_points': list(self.q_data_points), 'fwhm_values': list(self.fwhm_values)}


# add pointwise smearing funtion
class Pointwise(ResolutionFunction):
def __init__(self, q_data_points: list[np.ndarray]):
self.q_data_points = q_data_points
self.q = None

def smearing(self, q: Union[np.ndarray, float] = None) -> np.ndarray:

Qz = self.q_data_points[0]
R = self.q_data_points[1]
sQz = self.q_data_points[2]
Expand All @@ -87,19 +87,20 @@ def smearing(self, q: Union[np.ndarray, float] = None) -> np.ndarray:
def as_dict(
self, skip: Optional[List[str]] = None
) -> dict[str, str]: # skip is kept for consistency of the as_dict signature
return {'smearing': 'Pointwise',
'q_data_points': list(self.q_data_points[0]),
'R_data_points': list(self.q_data_points[1]),
'sQz_data_points': list(self.q_data_points[2])}
return {
'smearing': 'Pointwise',
'q_data_points': list(self.q_data_points[0]),
'R_data_points': list(self.q_data_points[1]),
'sQz_data_points': list(self.q_data_points[2]),
}

def gaussian_smearing(self, qt, Qz, R, sQz):
weights = np.exp(-0.5 * ((qt - Qz) / sQz) ** 2)
if np.sum(weights) == 0 or not np.isfinite(np.sum(weights)):
return np.sum(R)
weights /= (sQz * np.sqrt(2 * np.pi))
weights /= sQz * np.sqrt(2 * np.pi)
return np.sum(R * weights) / np.sum(weights)


def apply_smooth_smearing(self, Qz, R, sQzs):
"""
Apply smooth resolution smearing using convolution with Gaussian kernel.
Expand Down
7 changes: 3 additions & 4 deletions src/easyreflectometry/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from easyscience import global_object
from easyscience.fitting import AvailableMinimizers
from easyscience.fitting.fitter import DEFAULT_MINIMIZER
from easyscience.Objects.variable import Parameter
from easyscience.variable import Parameter
from scipp import DataGroup

from easyreflectometry.calculators import CalculatorFactory
Expand Down Expand Up @@ -173,7 +173,7 @@ def current_experiment_index(self, value: int) -> None:
if self._current_experiment_index != value:
self._current_experiment_index = value
# Resetting the model index to 0 when changing the experiment
#self.current_model_index = 0
# self.current_model_index = 0

@property
def created(self) -> bool:
Expand Down Expand Up @@ -283,8 +283,7 @@ def load_experiment_for_model_at_index(self, path: Union[Path, str], index: Opti
q = self._experiments[index].x
reflectivity = self._experiments[index].y
q_error = self._experiments[index].xe
resolution_function = Pointwise(
q_data_points=[q, reflectivity, q_error])
resolution_function = Pointwise(q_data_points=[q, reflectivity, q_error])
# resolution_function = LinearSpline(
# q_data_points=self._experiments[index].y,
# fwhm_values=np.sqrt(self._experiments[index].ye),
Expand Down
Loading
Loading