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

Pr/1.4.4 #210

Merged
merged 29 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f7acd77
Change the default behaviour of the logger so that it doesn't display…
mpvanderschelling Oct 25, 2023
138d4a0
Make DataGenerator.run method private
mpvanderschelling Oct 26, 2023
eaf6601
Handle similar bounds on add_float to make a constant parameter
mpvanderschelling Oct 26, 2023
80bf59d
Change iter-behaviour of ExperimentData object to provide ExperimentS…
mpvanderschelling Oct 26, 2023
c3198d1
add test
mpvanderschelling Oct 26, 2023
4770610
Fixes Get public access to ExperimentSample by providing index #188
mpvanderschelling Oct 26, 2023
c4e6b56
removed custom __getitem__ method ExperimentData
mpvanderschelling Oct 26, 2023
8c5bbf8
removed commented code
mpvanderschelling Oct 26, 2023
9b29a80
Fixes Get a way to extract input and output data from ExperimentData …
mpvanderschelling Oct 26, 2023
15ceae7
ExperimentData.store documentation is not correct
mpvanderschelling Oct 26, 2023
df3f5f1
Fixes #194
mpvanderschelling Oct 26, 2023
3b1e222
Merge pull request #197 from bessagroup/mpvanderschelling/issue193
mpvanderschelling Oct 27, 2023
63772d6
Merge pull request #196 from bessagroup/mpvanderschelling/issue186
mpvanderschelling Oct 27, 2023
0d74d03
Handle similar bounds on add_float to make a constant parameter
mpvanderschelling Oct 27, 2023
df9744a
Change iter-behaviour of ExperimentData object to provide ExperimentS…
mpvanderschelling Oct 27, 2023
8ebd193
ExperimentData.store documentation is not correct
mpvanderschelling Oct 27, 2023
db53827
added the reason why filename is optional
mpvanderschelling Oct 27, 2023
ecfd243
Merge pull request #199 from bessagroup/mpvanderschelling/issue189
mpvanderschelling Oct 27, 2023
88297a3
Merge pull request #203 from bessagroup/mpvanderschelling/issue190
mpvanderschelling Oct 27, 2023
e3dfef1
Merge pull request #198 from bessagroup/mpvanderschelling/issue195
mpvanderschelling Oct 27, 2023
208137c
Merge branch 'pr/1.4.4' into mpvanderschelling/issue192
mpvanderschelling Oct 27, 2023
f5f2ea5
Merge pull request #200 from bessagroup/mpvanderschelling/issue192
mpvanderschelling Oct 28, 2023
d7f9180
increased version number to 1.4.4
mpvanderschelling Oct 28, 2023
dc6664e
Increased version number to 1.4.4
mpvanderschelling Oct 28, 2023
452c53b
changed github workflows
mpvanderschelling Oct 28, 2023
f47bc0f
added more descriptive docstrings
mpvanderschelling Oct 30, 2023
9adc3f5
Merge branch 'pr/1.4.4' into mpvanderschelling/issue194
mpvanderschelling Oct 30, 2023
e11a003
flake8 error resolved at docstring
mpvanderschelling Oct 30, 2023
ae54591
Merge pull request #204 from bessagroup/mpvanderschelling/issue194
mpvanderschelling Oct 30, 2023
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
5 changes: 4 additions & 1 deletion .github/workflows/pr_to_pr.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
name: Pull request to pr/** branches
name: Pull request and push to pr/** branches

on:
pull_request:
branches:
- "pr/**"
push:
branches:
- "pr/**"

jobs:
check-coding-style:
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.4.3
1.4.4
4 changes: 2 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
project = 'f3dasm'
author = 'Martin van der Schelling'
copyright = '2022, Martin van der Schelling'
version = '1.4.3'
release = '1.4.3'
version = '1.4.4'
release = '1.4.4'


# -- General configuration ----------------------------------------------------
Expand Down
13 changes: 13 additions & 0 deletions docs/source/rst_doc_files/classes/design/experimentsample.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ An KeyError will be raised if the key is not found.
>>> experiment_sample.get('param_1')
0.0249

Manually iterating over ExperimentData
----------------------------------------

The :class:`~f3dasm.design.ExperimentData` object can be manually iterated over to get :class:`~f3dasm.design.ExperimentSample` objects for each experiment:

.. code-block:: python

>>> for experiment_sample in experiment_data:
... print(experiment_sample)
ExperimentSample(0 : {'x0': 0.8184054141827567, 'x1': 0.937852542255321, 'x2': 0.7376563782762678} - {})
ExperimentSample(1 : {'x0': 0.7203461491873061, 'x1': 0.7320604457665572, 'x2': 0.2524387342272223} - {})
ExperimentSample(2 : {'x0': 0.35449352388104904, 'x1': 0.11413412225748525, 'x2': 0.1467895592274866} - {})

Storing output parameters to the experiment sample
--------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion src/f3dasm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# =============================================================================


__version__ = '1.4.3'
__version__ = '1.4.4'


# Log welcome message and the version of f3dasm
Expand Down
83 changes: 76 additions & 7 deletions src/f3dasm/_src/datageneration/datagenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# Standard
import sys
from abc import abstractmethod
from functools import partial
from typing import Any, Callable

Expand Down Expand Up @@ -43,30 +44,80 @@ class DataGenerator:
"""Base class for a data generator"""

def pre_process(self, experiment_sample: ExperimentSample, **kwargs) -> None:
"""Function that handles the pre-processing"""
"""Interface function that handles the pre-processing of the data generator

Notes
-----
If not implemented the function will be skipped

The experiment_sample is cached inside the data generator. This
allows the user to access the experiment_sample in the pre_process, execute
and post_process functions as a class variable called self.experiment_sample.
"""
...

@abstractmethod
def execute(self, **kwargs) -> None:
"""Function that calls the FEM simulator the pre-processing"""
raise NotImplementedError("No execute function implemented!")
"""Interface function that handles the execution of the data generator

Raises
------
NotImplementedError
If the function is not implemented by the user

Notes
-----
The experiment_sample is cached inside the data generator. This
allows the user to access the experiment_sample in the pre_process, execute
and post_process functions as a class variable called self.experiment_sample.
"""

...

def post_process(self, experiment_sample: ExperimentSample, **kwargs) -> None:
"""Function that handles the post-processing"""
"""Interface function that handles the post-processing of the data generator

Notes
-----
If not implemented the function will be skipped

The experiment_sample is cached inside the data generator. This
allows the user to access the experiment_sample in the pre_process, execute
and post_process functions as a class variable called self.experiment_sample.
"""
...

@time_and_log
def run(self, experiment_sample: ExperimentSample, **kwargs) -> ExperimentSample:
"""Run the data generator
def _run(self, experiment_sample: ExperimentSample, **kwargs) -> ExperimentSample:
"""
Run the data generator
This function chains the following methods together

* pre_process(); to combine the experiment_sample and the parameters
of the data generator to an input file that can be used to run the data generator

* execute(); to run the data generator and generate the response of the experiment

* post_process(); to process the response of the experiment and store it back
in the experiment_sample

The function also caches the experiment_sample in the data generator. This
allows the user to access the experiment_sample in the pre_process, execute
and post_process functions as a class variable called self.experiment_sample.

Parameters
----------
ExperimentSample : ExperimentSample
The design to run the data generator on

kwargs : dict
The keyword arguments to pass to the pre_process, execute and post_process

Returns
-------
ExperimentSample
Processed design
Processed design with the response of the data generator saved in the
experiment_sample
"""
# Cache the design
self.experiment_sample: ExperimentSample = experiment_sample
Expand All @@ -88,7 +139,25 @@ def _post_simulation(self) -> None:
...

def add_pre_process(self, func: Callable, **kwargs):
"""Add a pre-processing function to the data generator

Parameters
----------
func : Callable
The function to add to the pre-processing
kwargs : dict
The keyword arguments to pass to the pre-processing function
"""
self.pre_process = partial(func, **kwargs)

def add_post_process(self, func: Callable, **kwargs):
"""Add a post-processing function to the data generator

Parameters
----------
func : Callable
The function to add to the post-processing
kwargs : dict
The keyword arguments to pass to the post-processing function
"""
self.post_process = partial(func, **kwargs)
2 changes: 1 addition & 1 deletion src/f3dasm/_src/datageneration/functions/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def execute(self, experiment_sample: ExperimentSample) -> ExperimentSample:
experiment_sample["y"] = self(x).ravel().astype(np.float32)
return experiment_sample

def run(self, experiment_sample: ExperimentSample, **kwargs) -> ExperimentSample:
def _run(self, experiment_sample: ExperimentSample, **kwargs) -> ExperimentSample:
return self.execute(experiment_sample)

def _retrieve_original_input(self, x: np.ndarray):
Expand Down
52 changes: 50 additions & 2 deletions src/f3dasm/_src/design/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
from __future__ import annotations

# Standard
import math
import pickle
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Dict, Iterator, List, Sequence, Type
from typing import Any, Dict, Iterable, Iterator, List, Sequence, Type

# Third-party core
import numpy as np
Expand Down Expand Up @@ -252,7 +253,14 @@ def add_int(self, name: str, low: int, high: int, step: int = 1):
>>> domain.add_int('param1', 0, 10, 2)
>>> domain.space
{'param1': DiscreteParameter(lower_bound=0, upper_bound=10, step=2)}

Note
----
If the lower and upper bound are equal, then a constant parameter
will be added to the domain!
"""
if low == high:
self.add_constant(name, low)
self._add(name, DiscreteParameter(low, high, step))

def add_float(self, name: str, low: float, high: float, log: bool = False):
Expand All @@ -275,8 +283,16 @@ def add_float(self, name: str, low: float, high: float, log: bool = False):
>>> domain.add_float('param1', 0., 10., log=True)
>>> domain.space
{'param1': ContinuousParameter(lower_bound=0., upper_bound=10., log=True)}

Note
----
If the lower and upper bound are equal, then a constant parameter
will be added to the domain!
"""
self._add(name, ContinuousParameter(low, high, log))
if math.isclose(low, high):
self.add_constant(name, low)
else:
self._add(name, ContinuousParameter(low, high, log))

def add_category(self, name: str, categories: Sequence[CategoricalType]):
"""Add a new categorical input parameter to the domain.
Expand Down Expand Up @@ -573,6 +589,38 @@ def _filter(self, type: Type[Parameter]) -> Domain:
if isinstance(parameter, type)}
)

def select(self, names: str | Iterable[str]) -> Domain:
"""Select a subset of parameters from the domain.

Parameters
----------

names : str or Iterable[str]
The names of the parameters to select.

Returns
-------
Domain
A new domain with the selected parameters.

Example
-------
>>> domain = Domain()
>>> domain.space = {
... 'param1': ContinuousParameter(lower_bound=0., upper_bound=1.),
... 'param2': DiscreteParameter(lower_bound=0, upper_bound=8),
... 'param3': CategoricalParameter(categories=['cat1', 'cat2'])
... }
>>> domain.select(['param1', 'param3'])
Domain({'param1': ContinuousParameter(lower_bound=0, upper_bound=1),
'param3': CategoricalParameter(categories=['cat1', 'cat2'])})
"""

if isinstance(names, str):
names = [names]

return Domain(space={key: self.space[key] for key in names})

# Miscellaneous
# =============================================================================

Expand Down
17 changes: 17 additions & 0 deletions src/f3dasm/_src/experimentdata/_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,23 @@ def n_best_samples(self, nosamples: int, column_name: List[str] | str) -> pd.Dat
"""
return self.data.nsmallest(n=nosamples, columns=column_name)

def select_columns(self, columns: Iterable[str] | str) -> _Data:
"""Filter the data on the selected columns.

Parameters
----------
columns : Iterable[str] | str
The columns to select.

Returns
-------
_Data
The data only with the selected columns
"""
# This is necessary otherwise self.data[columns] will be a Series
if isinstance(columns, str):
columns = [columns]
return _Data(self.data[columns])
# Append and remove data
# =============================================================================

Expand Down
Loading