Skip to content

Commit

Permalink
Merge branch 'develop' into 58-pre-commit
Browse files Browse the repository at this point in the history
  • Loading branch information
BradyPlanden committed Oct 26, 2023
2 parents 344e85f + 7fb11a4 commit 87a619e
Show file tree
Hide file tree
Showing 24 changed files with 145 additions and 37 deletions.
3 changes: 3 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import pytest
import matplotlib

matplotlib.use("Template")


def pytest_addoption(parser):
Expand Down
1 change: 0 additions & 1 deletion examples/scripts/mle.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
print("Estimated parameters:")
print(x1)


# Show the generated data
simulated_values = problem.evaluate(x1[:2])

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pybop
import pandas as pd
import numpy as np

# Form observations
Measurements = pd.read_csv("examples/scripts/Chen_example.csv", comment="#").to_numpy()
Expand Down Expand Up @@ -27,7 +28,7 @@
),
]

parameterisation = pybop.Parameterisation(
parameterisation = pybop.Optimisation(
model, observations=observations, fit_parameters=params
)

Expand Down
20 changes: 12 additions & 8 deletions pybop/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,34 @@
# Float format: a float can be converted to a 17 digit decimal and back without
# loss of information
FLOAT_FORMAT = "{: .17e}"
# Absolute path to the PyBOP repo
script_path = os.path.abspath(__file__)
# Absolute path to the pybop module
script_path = os.path.dirname(__file__)

#
# Model Classes
#
from .models import BaseModel, lithium_ion
from .models import lithium_ion
from .models.BaseModel import BaseModel

#
# Parameterisation class
#
from .identification import Parameterisation, ParameterSet, Parameter, Observed
from .parameters.parameter_set import ParameterSet
from .parameters.parameter import Parameter
from .datasets.observations import Observed

#
# Priors class
#
from .priors import Gaussian, Uniform, Exponential
from .parameters.priors import Gaussian, Uniform, Exponential

#
# Optimisation class
#
from .optimisation import BaseOptimisation
from .optimisation.NLoptOptimize import NLoptOptimize
from .optimisation.SciPyMinimize import SciPyMinimize
from .optimisation import Optimisation
from .optimisers import BaseOptimiser
from .optimisers.NLoptOptimize import NLoptOptimize
from .optimisers.SciPyMinimize import SciPyMinimize

#
# Remove any imported modules, so we don't expose them as part of pybop
Expand Down
File renamed without changes.
Empty file added pybop/datasets/__init__.py
Empty file.
File renamed without changes.
4 changes: 0 additions & 4 deletions pybop/identification/__init__.py

This file was deleted.

4 changes: 2 additions & 2 deletions pybop/models/BaseModel.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pybamm


class BaseModel:
class BaseModel():
"""
Base class for PyBOP models
"""
Expand Down Expand Up @@ -102,7 +102,7 @@ def simulate(self, inputs, t_eval):
if self._built_model is None:
raise ValueError("Model must be built before calling simulate")
else:
if inputs is isinstance(dict):
if not isinstance(inputs, dict):
inputs_dict = {
key: inputs[i] for i, key in enumerate(self.fit_parameters)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import numpy as np


class Parameterisation:
class Optimisation:
"""
Parameterisation class for pybop.
Optimisation class for PyBOP.
"""

def __init__(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
class BaseOptimisation:
class BaseOptimiser:
"""
Base class for the optimisation methods.
"""

def __init__(self):
self.name = "Base Optimisation"
self.name = "Base Optimiser"

def optimise(self, cost_function, x0, bounds, method=None):
"""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import nlopt
from .BaseOptimisation import BaseOptimisation
from .BaseOptimiser import BaseOptimiser


class NLoptOptimize(BaseOptimisation):
class NLoptOptimize(BaseOptimiser):
"""
Wrapper class for the NLOpt optimisation class. Extends the BaseOptimisation class.
Wrapper class for the NLOpt optimisation class. Extends the BaseOptimiser class.
"""

def __init__(self, method=None, x0=None, xtol=None):
super().__init__()
self.name = "NLOpt Optimisation"
self.name = "NLOpt Optimiser"

if method is not None:
self.opt = nlopt.opt(method, len(x0))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from scipy.optimize import minimize
from .BaseOptimisation import BaseOptimisation
from .BaseOptimiser import BaseOptimiser


class SciPyMinimize(BaseOptimisation):
class SciPyMinimize(BaseOptimiser):
"""
Wrapper class for the Scipy optimisation class. Extends the BaseOptimisation class.
Wrapper class for the Scipy optimisation class. Extends the BaseOptimiser class.
"""

def __init__(self, cost_function, x0, bounds=None, options=None):
Expand All @@ -14,7 +14,7 @@ def __init__(self, cost_function, x0, bounds=None, options=None):
self.x0 = x0 or cost_function.x0
self.bounds = bounds
self.options = options
self.name = "Scipy Optimisation"
self.name = "Scipy Optimiser"

def _runoptimise(self):
"""
Expand Down
Empty file added pybop/optimisers/__init__.py
Empty file.
Empty file added pybop/parameters/__init__.py
Empty file.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"scipy>=1.3",
"pandas>=1.0",
"nlopt>=2.6",
"pints>=0.5",
],
# https://pypi.org/classifiers/
classifiers=[],
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/test_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import pybop
import numpy as np
import pytest
import runpy
import os


class TestExamples:
"""
A class to test the example scripts.
"""

@pytest.mark.unit
def test_example_scripts(self):
path_to_example_scripts = os.path.join(
pybop.script_path, "..", "examples", "scripts"
)
for example in os.listdir(path_to_example_scripts):
if example.endswith(".py"):
runpy.run_path(os.path.join(path_to_example_scripts, example))
34 changes: 34 additions & 0 deletions tests/unit/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import pybop
import numpy as np
import pytest
import runpy
import os


class TestModels:
"""
A class to test the models.
"""

@pytest.mark.unit
def test_simulate_without_build_model(self):
# Define model
model = pybop.lithium_ion.SPM()

with pytest.raises(
ValueError, match="Model must be built before calling simulate"
):
model.simulate(None, None)

@pytest.mark.unit
def test_build(self):
model = pybop.lithium_ion.SPM()
model.build()
assert model.built_model is not None

@pytest.mark.unit
def test_n_parameters(self):
model = pybop.BaseModel()
n = model.n_outputs()
assert isinstance(n, int)

22 changes: 22 additions & 0 deletions tests/unit/test_parameter_sets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pybop
import numpy as np
import pytest
import runpy
import os


class TestParameterSets:
"""
A class to test parameter sets.
"""

@pytest.mark.unit
def test_parameter_set(self):
# Tests parameter set creation
with pytest.raises(ValueError):
pybop.ParameterSet("pybamms", "Chen2020")

parameter_test = pybop.ParameterSet("pybamm", "Chen2020")
np.testing.assert_allclose(
parameter_test["Negative electrode active material volume fraction"], 0.75
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import pybop
import pybamm
import numpy as np
import pytest
import numpy as np


class TestModelParameterisation:
"""
A class to test the model parameterisation methods.
"""

class TestParameterisation:
@pytest.mark.unit
def test_spm(self):
# Define model
Expand Down Expand Up @@ -35,16 +39,17 @@ def test_spm(self):
),
]

parameterisation = pybop.Parameterisation(
parameterisation = pybop.Optimisation(
model, observations=observations, fit_parameters=params
)

# get RMSE estimate using NLOpt
results, last_optim, num_evals = parameterisation.rmse(
signal="Voltage [V]", method="nlopt"
)
# Assertions
np.testing.assert_allclose(last_optim, 1e-3, atol=1e-2)

# Assertions (for testing purposes only)
np.testing.assert_allclose(last_optim, 0, atol=1e-2)
np.testing.assert_allclose(results, x0, atol=1e-1)

@pytest.mark.unit
Expand Down Expand Up @@ -77,17 +82,18 @@ def test_spme(self):
),
]

parameterisation = pybop.Parameterisation(
parameterisation = pybop.Optimisation(
model, observations=observations, fit_parameters=params
)

# get RMSE estimate using NLOpt
results, last_optim, num_evals = parameterisation.rmse(
signal="Voltage [V]", method="nlopt"
)
# Assertions
np.testing.assert_allclose(last_optim, 1e-3, atol=1e-2)
np.testing.assert_allclose(results, x0, atol=1e-1)

# Assertions (for testing purposes only)
np.testing.assert_allclose(last_optim, 0, atol=1e-2)
np.testing.assert_allclose(results, x0, rtol=1e-1)

def getdata(self, model, x0):
model.parameter_set = model.pybamm_model.default_parameter_values
Expand Down
22 changes: 22 additions & 0 deletions tests/unit/test_priors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pybop
import numpy as np
import pytest
import runpy
import os


class TestPriors:
"""
A class to test the priors.
"""

@pytest.mark.unit
def test_priors(self):
# Tests priors
Gaussian = pybop.Gaussian(0.5, 1)
Uniform = pybop.Uniform(0, 1)
Exponential = pybop.Exponential(1)

np.testing.assert_allclose(Gaussian.pdf(0.5), 0.3989422804014327, atol=1e-4)
np.testing.assert_allclose(Uniform.pdf(0.5), 1, atol=1e-4)
np.testing.assert_allclose(Exponential.pdf(1), 0.36787944117144233, atol=1e-4)

0 comments on commit 87a619e

Please sign in to comment.