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

Feature/add cadet docker api #180

Open
wants to merge 92 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
508983a
Add qNParEGO Ax MOO Interface
ronald-jaepel Apr 22, 2024
fdb7dcf
Relax tolerance for MOO convergence test
ronald-jaepel Apr 22, 2024
69a5478
Unify calling evaluation functions for individuals and populations
schmoelder Apr 21, 2024
1a4debb
Ensure callback dirs are created for final callback
ronald-jaepel Apr 29, 2024
9720966
Update docstrings
schmoelder Nov 24, 2023
83fff8f
Add method to create fraction
schmoelder Nov 24, 2023
8cc02e1
Add `start` and `end` times to `Fraction`
schmoelder Jan 19, 2024
159b374
Specify and validate reference type for difference metrics
schmoelder Jan 19, 2024
11c59f4
Add classes to __all__
schmoelder Jan 20, 2024
4d7fc10
Add `only_transforms_solution` flag
schmoelder Jan 22, 2024
a8ed736
Only resample if flag is set
schmoelder Jan 22, 2024
d20d9cd
Formatting
schmoelder Jan 20, 2024
52e33bf
Fix typo
schmoelder Mar 2, 2024
a59372a
Add FractionationReference
schmoelder Jan 19, 2024
8f0faf6
Add FractionationSSE
schmoelder Jan 19, 2024
6bbb6c8
Fix add_concentration_profile (#140)
schmoelder Jun 19, 2024
12d862b
Always inherit cadet path
ronald-jaepel May 22, 2024
19e5457
Add method to calculate volumetric flow rate from velocity.
schmoelder Feb 15, 2023
3356cde
Rename .t0 to .calculate_interstitial_rt in Cstr
ronald-jaepel Mar 20, 2024
6fd5a44
Do not modify LD_LIBRARY_PATH when setting install_path
schmoelder Jun 17, 2024
618fb1f
Adapt to new DG interface in CADET-Core
schmoelder Mar 20, 2024
8ce41f3
Fix using minute for x-Axis
schmoelder Jun 17, 2024
1c9251f
Freeze discretization attributes
schmoelder Jun 17, 2024
4f1671b
Update docstrings
schmoelder Jun 17, 2024
7ddabeb
Fix incorrect declaration in AntiLangmuir as optional
AntoniaBerger May 22, 2024
cdc11b9
Change AntiLangmuir coefficient from SizedUnsignedList to SizedList
AntoniaBerger Jun 10, 2024
6150667
Raise exception when adding connections to Inlets or from Outlets
schmoelder Jun 25, 2024
e706472
Fix header level in documentation for unit operation
schmoelder Jun 25, 2024
2e6a7e3
Fix bug when adding linear constraints
schmoelder Jun 26, 2024
39402fe
Fix plot_at_position
hannahlanzrath Jul 3, 2024
0f900b3
Fix divide by zero error in pearsonr_mat
ronald-jaepel Jul 8, 2024
ead85ce
Avoid duplicate entries in user_solution_times
schmoelder Jun 21, 2024
736a4b4
Improve tearDown after tests
schmoelder Dec 9, 2023
b9e637e
Add FanoutCache
schmoelder Mar 14, 2024
b114674
Add colloidal binding model
Jun 20, 2024
3a177b7
Add support for numpy v2.0.0
schmoelder Jul 22, 2024
e85ca8d
Fix typo in set_diameter methods
schmoelder Aug 5, 2024
022ecf3
Fix bug when adding linear equality constraints
schmoelder Jun 26, 2024
b715f57
Explicitly specify support for bounds
schmoelder Jun 26, 2024
e0ebd09
Return np.array for linear constraints
schmoelder Jun 26, 2024
8032e81
Fix comparison logic for linear equality constraints
schmoelder Jun 26, 2024
498f64f
Use common optimizer interface for tolerances
schmoelder Jun 26, 2024
407eba8
Make optimial solution a property
schmoelder Jun 27, 2024
a68557e
Formatting
schmoelder Jun 26, 2024
5d97c65
Add option to (not) close cache on pruning
schmoelder Jun 26, 2024
9174bd7
Do not plot figures if progress_frequency is None
schmoelder Jun 26, 2024
1673101
Use in-memory cache for testing optimizer behaviour
schmoelder Jun 26, 2024
e59d9ae
Update population size in non-default parameters
schmoelder Jun 26, 2024
76e03e8
Add NelderMead and COBYLA to optimizer tests
schmoelder Jun 27, 2024
0a5fba1
Add type hints and update docstrings
schmoelder Jun 28, 2024
4b20473
Add method to evaluate bounds violation
schmoelder Jun 28, 2024
061def5
Cast np.bool_ to bool
schmoelder Jun 29, 2024
32f6a29
Allow evaluation of population for getting (in)dependent values
schmoelder Jun 28, 2024
572e96e
Add option to evaluate nonlinear constraints when checking individual
schmoelder Jun 28, 2024
e4cc118
Rename eps_eq -> eps_lineq
schmoelder Jun 28, 2024
b3fbe27
Make callback error logger warning more verbose.
ronald-jaepel Aug 6, 2024
1d1037b
Update gets_dependent_variables decorators
schmoelder Jul 31, 2024
3a8d88e
Rename decorator wrapper functions to improve stacktrace readability.
ronald-jaepel Jul 31, 2024
815f4a4
Add tolerance argument for constraint violation check methods
schmoelder Aug 6, 2024
3b87fe8
Handle maximum number of initial evaluations in Ax
schmoelder Aug 8, 2024
0115300
Distinguish between different constraint violations
schmoelder Jun 28, 2024
612099d
Add MCTDiscretization
hannahlanzrath Jul 12, 2024
c17b91c
Add MCTRecorder
schmoelder Jul 12, 2024
65591fa
Add ports to unitOperation
hannahlanzrath Jul 12, 2024
c5c06c7
Add ports to flowSheet
hannahlanzrath Jul 12, 2024
5ae2b84
Add ports to process
hannahlanzrath Jul 12, 2024
29404d1
Add ports to carouselBuilder
daklauss Jul 12, 2024
f7774f1
Add ports to compartmentBuilder
hannahlanzrath Jul 12, 2024
9f1e689
Add ports to simulationResults
daklauss Jul 12, 2024
546830c
Add ports to cadetAdapter
daklauss Jul 12, 2024
c0babf2
Add singelton dimension handling to solution
daklauss Aug 1, 2024
4e8dad5
Add method to get information about CADET version
hannahlanzrath Aug 1, 2024
e1e624f
Formatting
schmoelder Aug 14, 2024
5fed4a8
Update tests to pytest
hannahlanzrath Aug 1, 2024
29b5066
Add create_LWE
hannahlanzrath Aug 1, 2024
0794a23
Add LWE tests to test_cadet_adapter
hannahlanzrath Aug 1, 2024
36adbeb
Fix default value for start time when creating fractions
schmoelder Oct 2, 2024
1458a0b
Fix loading of multi-cycle solutions
ronald-jaepel Sep 26, 2024
336ae35
Pin ax version
schmoelder Nov 14, 2024
e1be7cb
Temporarily disable Windows tests to avoid crashes
schmoelder Nov 14, 2024
66d6b9d
Pin CADET-Python version
schmoelder Nov 14, 2024
35ba311
Fix AxInterface options
schmoelder Nov 14, 2024
20ead9c
Adapt cadetAdapter.py to match new install_path settings in CADET-Pyt…
ronald-jaepel Aug 16, 2024
bdc937d
Raise required CADET-Python version to v1.0
ronald-jaepel Nov 14, 2024
4d9d3d5
Adapt to new CSTR interface.
ronald-jaepel Nov 15, 2024
8b4dc27
Deprecate Mambaforge
schmoelder Oct 2, 2024
c2383f8
Improve cleanup after tests
schmoelder Nov 15, 2024
c5b4842
Remove `setup.cfg`
schmoelder Jul 22, 2024
12d7def
For mobile phase modulator binding add linear threshold parameter.
ronald-jaepel Aug 2, 2024
ccdf509
Add test for mobile phase modulator binding model.
ronald-jaepel Nov 14, 2024
8384f14
Use SingleTaskGP instead of FixedNoiseGP as recommended in the Deprec…
flo-schu Nov 19, 2024
f641e7d
Add docker_container property to CADETAdapter
ronald-jaepel Nov 20, 2024
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: 2 additions & 3 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ jobs:
os: [ubuntu-latest]
python-version: ["3.10", "3.11", "3.12"]
include:
- os: windows-latest
python-version: "3.12"
# - os: windows-latest
# python-version: "3.12"
- os: macos-12
python-version: "3.12"

Expand All @@ -40,7 +40,6 @@ jobs:
- name: Setup Conda Environment
uses: conda-incubator/setup-miniconda@v3
with:
miniforge-variant: Mambaforge
miniforge-version: latest
use-mamba: true
activate-environment: cadet-process
Expand Down
26 changes: 13 additions & 13 deletions CADETProcess/comparison/comparator.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def metrics(self):
return self._metrics

@property
def n_diffference_metrics(self):
def n_difference_metrics(self):
"""int: Number of difference metrics in the Comparator."""
return len(self.metrics)

Expand Down Expand Up @@ -242,11 +242,11 @@ def setup_comparison_figure(
tuple
A tuple of the comparison figure(s) and axes object(s).
"""
if self.n_diffference_metrics == 0:
if self.n_difference_metrics == 0:
return (None, None)

comparison_fig_all, comparison_axs_all = plotting.setup_figure(
n_rows=self.n_diffference_metrics,
n_rows=self.n_difference_metrics,
squeeze=False
)

Expand All @@ -255,7 +255,7 @@ def setup_comparison_figure(

comparison_fig_ind: list[Figure] = []
comparison_axs_ind: list[Axes] = []
for i in range(self.n_diffference_metrics):
for i in range(self.n_difference_metrics):
fig, axs = plt.subplots()
comparison_fig_ind.append(fig)
comparison_axs_ind.append(axs)
Expand All @@ -271,33 +271,33 @@ def setup_comparison_figure(

def plot_comparison(
self,
simulation_results: list[SimulationResults],
simulation_results: SimulationResults,
axs: Axes | list[Axes] | None = None,
figs: Figure | list[Figure] | None = None,
file_name: str | None = None,
show: bool = True,
plot_individual: bool = False,
use_minutes: bool = True,
x_axis_in_minutes: bool = True,
) -> tuple[list[Figure], list[Axes]]:
"""
Plot the comparison of the simulation results with the reference data.

Parameters
----------
simulation_results : list of SimulationResults
List of simulation results to compare to reference data.
axs : list of AxesSubplot, optional
simulation_results : SimulationResults
Simulation results to compare to reference data.
axs : list of Axes, optional
List of subplot axes to use for plotting the metrics.
figs : list of Figure, optional
figs : list of Figures, optional
List of figures to use for plotting the metrics.
file_name : str, optional
Name of the file to save the figure to.
show : bool, optional
If True, displays the figure(s) on the screen.
plot_individual : bool, optional
If True, generates a separate figure for each metric.
use_minutes : bool, optional
Option to use x-aches (time) in minutes, default is set to True.
x_axis_in_minutes: bool, optional
If True, the x-axis will be plotted using minutes. The default is True.

Returns
-------
Expand Down Expand Up @@ -331,7 +331,7 @@ def plot_comparison(
'label': 'reference',
}
ref_time = metric.reference.time
if use_minutes:
if x_axis_in_minutes:
ref_time = ref_time / 60

plotting.add_overlay(ax, metric.reference.solution, ref_time, **plot_args)
Expand Down
118 changes: 107 additions & 11 deletions CADETProcess/comparison/difference.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@

from CADETProcess import CADETProcessError
from CADETProcess.dataStructure import UnsignedInteger
from CADETProcess.solution import SolutionBase, slice_solution
from CADETProcess.solution import SolutionIO, slice_solution
from CADETProcess.metric import MetricBase
from CADETProcess.reference import ReferenceIO, FractionationReference
from .shape import pearson, pearson_offset
from .peaks import find_peaks, find_breakthroughs

Expand All @@ -24,6 +25,7 @@
'Shape',
'PeakHeight', 'PeakPosition',
'BreakthroughHeight', 'BreakthroughPosition',
'FractionationSSE',
]


Expand Down Expand Up @@ -74,7 +76,7 @@ class DifferenceBase(MetricBase):

Parameters
----------
reference : ReferenceIO
reference : ReferenceBase
Reference used for calculating difference metric.
components : {str, list}, optional
Solution components to be considered.
Expand All @@ -97,6 +99,8 @@ class DifferenceBase(MetricBase):
If True, normalize data. The default is False.
"""

_valid_references = ()

def __init__(
self,
reference,
Expand All @@ -106,14 +110,15 @@ def __init__(
start=None,
end=None,
transform=None,
only_transforms_array=True,
resample=True,
smooth=False,
normalize=False):
"""Initialize an instance of DifferenceBase.

Parameters
----------
reference : ReferenceIO
reference : ReferenceBase
Reference used for calculating difference metric.
components : {str, list}, optional
Solution components to be considered.
Expand All @@ -128,6 +133,8 @@ def __init__(
End time of solution slice to be considerd. The default is None.
transform : callable, optional
Function to transform solution. The default is None.
only_transforms_array: bool, optional
If True, only transform np array of solution object. The default is True.
resample : bool, optional
If True, resample data. The default is True.
smooth : bool, optional
Expand All @@ -143,6 +150,7 @@ def __init__(
self.start = start
self.end = end
self.transform = transform
self.only_transforms_array = only_transforms_array
self.resample = resample
self.smooth = smooth
self.normalize = normalize
Expand All @@ -165,8 +173,11 @@ def reference(self):

@reference.setter
def reference(self, reference):
if not isinstance(reference, SolutionBase):
raise TypeError("Expected SolutionBase")
if not isinstance(reference, self._valid_references):
raise TypeError(
f"Invalid reference type: {type(reference)}. "
f"Expected types: {self._valid_references}."
)

self._reference = copy.deepcopy(reference)
if self.resample and not self._reference.is_resampled:
Expand Down Expand Up @@ -221,11 +232,12 @@ def resamples_smoothes_and_normalizes_solution(func):
@wraps(func)
def wrapper(self, solution, *args, **kwargs):
solution = copy.deepcopy(solution)
solution.resample(
self._reference.time[0],
self._reference.time[-1],
len(self._reference.time),
)
if self.resample:
solution.resample(
self._reference.time[0],
self._reference.time[-1],
len(self._reference.time),
)
if self.normalize and not solution.is_normalized:
solution.normalize()
if self.smooth and not solution.is_smoothed:
Expand All @@ -241,7 +253,11 @@ def transforms_solution(func):
def wrapper(self, solution, *args, **kwargs):
if self.transform is not None:
solution = copy.deepcopy(solution)
solution.solution = self.transform(solution.solution)

if self.only_transforms_array:
solution.solution = self.transform(solution.solution)
else:
solution = self.transform(solution)

value = func(self, solution, *args, **kwargs)
return value
Expand Down Expand Up @@ -321,6 +337,8 @@ def calculate_sse(simulation, reference):
class SSE(DifferenceBase):
"""Sum of squared errors (SSE) difference metric."""

_valid_references = (ReferenceIO, SolutionIO)

def _evaluate(self, solution):
sse = calculate_sse(solution.solution, self.reference.solution)

Expand Down Expand Up @@ -348,6 +366,8 @@ def calculate_rmse(simulation, reference):
class RMSE(DifferenceBase):
"""Root mean squared errors (RMSE) difference metric."""

_valid_references = (SolutionIO, ReferenceIO)

def _evaluate(self, solution):
rmse = calculate_rmse(solution.solution, self.reference.solution)

Expand All @@ -357,6 +377,8 @@ def _evaluate(self, solution):
class NRMSE(DifferenceBase):
"""Normalized root mean squared errors (RRMSE) difference metric."""

_valid_references = (SolutionIO, ReferenceIO)

def _evaluate(self, solution):
rmse = calculate_rmse(solution.solution, self.reference.solution)
nrmse = rmse / np.max(self.reference.solution, axis=0)
Expand All @@ -373,6 +395,8 @@ class Norm(DifferenceBase):
The order of the norm.
"""

_valid_references = (SolutionIO, ReferenceIO)

order = UnsignedInteger()

def _evaluate(self, solution):
Expand All @@ -398,6 +422,8 @@ class L2(Norm):
class AbsoluteArea(DifferenceBase):
"""Absolute difference in area difference metric."""

_valid_references = (SolutionIO, ReferenceIO)

def _evaluate(self, solution):
"""np.array: Absolute difference in area compared to reference.

Expand All @@ -418,6 +444,8 @@ def _evaluate(self, solution):
class RelativeArea(DifferenceBase):
"""Relative difference in area difference metric."""

_valid_references = (SolutionIO, ReferenceIO)

def _evaluate(self, solution):
"""np.array: Relative difference in area compared to reference.

Expand Down Expand Up @@ -462,6 +490,8 @@ class Shape(DifferenceBase):

"""

_valid_references = (SolutionIO, ReferenceIO)

@wraps(DifferenceBase.__init__)
def __init__(
self, *args,
Expand Down Expand Up @@ -645,6 +675,8 @@ class PeakHeight(DifferenceBase):
Contains the normalization factors for each peak in each component.
"""

_valid_references = (SolutionIO, ReferenceIO)

@wraps(DifferenceBase.__init__)
def __init__(
self, *args,
Expand Down Expand Up @@ -737,6 +769,8 @@ class PeakPosition(DifferenceBase):
Contains the normalization factors for each peak in each component.
"""

_valid_references = (SolutionIO, ReferenceIO)

@wraps(DifferenceBase.__init__)
def __init__(self, *args, normalize_metrics=True, normalization_factor=None, **kwargs):
"""Initialize PeakPosition object.
Expand Down Expand Up @@ -823,6 +857,8 @@ class BreakthroughHeight(DifferenceBase):

"""

_valid_references = (SolutionIO, ReferenceIO)

@wraps(DifferenceBase.__init__)
def __init__(self, *args, normalize_metrics=True, **kwargs):
"""Initialize BreakthroughHeight metric.
Expand Down Expand Up @@ -874,6 +910,8 @@ def _evaluate(self, solution):
class BreakthroughPosition(DifferenceBase):
"""Absolute difference in breakthrough curve position difference metric."""

_valid_references = (SolutionIO, ReferenceIO)

@wraps(DifferenceBase.__init__)
def __init__(self, *args, normalize_metrics=True, normalization_factor=None, **kwargs):
"""
Expand Down Expand Up @@ -935,3 +973,61 @@ def _evaluate(self, solution):
]

return np.abs(score)


class FractionationSSE(DifferenceBase):
"""Fractionation based score using SSE."""

_valid_references = (FractionationReference)

@wraps(DifferenceBase.__init__)
def __init__(self, *args, normalize_metrics=True, normalization_factor=None, **kwargs):
"""
Initialize the FractionationSSE object.

Parameters
----------
*args :
Positional arguments for DifferenceBase.
normalize_metrics : bool, optional
Whether to normalize the metrics. Default is True.
normalization_factor : float, optional
Factor to use for normalization.
If None, it is set to the maximum of the difference between the reference
breakthrough and the start time, and the difference between the end time and
the reference breakthrough.
**kwargs : dict
Keyword arguments passed to the base class constructor.

"""
super().__init__(*args, resample=False, only_transforms_array=False, **kwargs)

if not isinstance(self.reference, FractionationReference):
raise TypeError("FractionationSSE can only work with FractionationReference")

def transform(solution):
solution = copy.deepcopy(solution)
solution_fractions = [
solution.create_fraction(frac.start, frac.end)
for frac in self.reference.fractions
]

solution.time = np.array([(frac.start + frac.end)/2 for frac in solution_fractions])
solution.solution = np.array([frac.concentration for frac in solution_fractions])

return solution

self.transform = transform

def _evaluate(self, solution):
"""np.array: Difference in breakthrough position (time).

Parameters
----------
solution : SolutionIO
Concentration profile of simulation.

"""
sse = calculate_sse(solution.solution, self.reference.solution)

return sse
Loading
Loading