Skip to content

Commit

Permalink
Reformat signal into a list (#147)
Browse files Browse the repository at this point in the history
* Make Dataset contain a dictionary

* Extend signal to a list of strings

* Align with set_max_iterations

* Turn signal into list

* Parameterise and test multiple signals

* Update CHANGELOG.md

* Relax test_multiple_signals assertion

* Create test_dataset.py

* Update Dataset to accept PyBaMM Solution

* Update test_problem.py

* Move signal to BaseProblem

* Add test on signal type
  • Loading branch information
NicolaCourtier authored Dec 14, 2023
1 parent c80e0d8 commit 14881c3
Show file tree
Hide file tree
Showing 23 changed files with 395 additions and 231 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- [#116](https://github.com/pybop-team/PyBOP/issues/116) - Adds PSO, SNES, XNES, ADAM, and IPropMin optimisers to PintsOptimisers() class
- [#38](https://github.com/pybop-team/PyBOP/issues/38) - Restructures the Problem classes ahead of adding a design optimisation example
- [#120](https://github.com/pybop-team/PyBOP/issues/120) - Updates the parameterisation test settings including the number of iterations
- [#145](https://github.com/pybop-team/PyBOP/issues/145) - Reformats Dataset to contain a dictionary and signal into a list of strings

## Bug Fixes

Expand Down
12 changes: 7 additions & 5 deletions examples/notebooks/spm_nlopt.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -277,11 +277,13 @@
"outputs": [],
"source": [
"pyb_model = pybop.lithium_ion.SPM()\n",
"dataset = [\n",
" pybop.Dataset(\"Time [s]\", synthetic_sol[\"Time [s]\"].data),\n",
" pybop.Dataset(\"Current function [A]\", synthetic_sol[\"Current [A]\"].data),\n",
" pybop.Dataset(\"Terminal voltage [V]\", corrupt_V),\n",
"]"
"dataset = pybop.Dataset(\n",
" {\n",
" \"Time [s]\": synthetic_sol[\"Time [s]\"].data,\n",
" \"Current function [A]\": synthetic_sol[\"Current [A]\"].data,\n",
" \"Terminal voltage [V]\": corrupt_V,\n",
" }\n",
")"
]
},
{
Expand Down
13 changes: 8 additions & 5 deletions examples/scripts/ecm_CMAES.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,14 @@
values = model.predict(t_eval=t_eval)
corrupt_values = values["Voltage [V]"].data + np.random.normal(0, sigma, len(t_eval))

dataset = [
pybop.Dataset("Time [s]", t_eval),
pybop.Dataset("Current function [A]", values["Current [A]"].data),
pybop.Dataset("Voltage [V]", corrupt_values),
]
# Form dataset
dataset = pybop.Dataset(
{
"Time [s]": t_eval,
"Current function [A]": values["Current [A]"].data,
"Voltage [V]": corrupt_values,
}
)

# Generate problem, cost function, and optimisation class
problem = pybop.FittingProblem(model, parameters, dataset)
Expand Down
14 changes: 8 additions & 6 deletions examples/scripts/spm_CMAES.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
values = model.predict(t_eval=t_eval)
corrupt_values = values["Voltage [V]"].data + np.random.normal(0, sigma, len(t_eval))

# Form dataset for optimisation
dataset = [
pybop.Dataset("Time [s]", t_eval),
pybop.Dataset("Current function [A]", values["Current [A]"].data),
pybop.Dataset("Voltage [V]", corrupt_values),
]
# Form dataset
dataset = pybop.Dataset(
{
"Time [s]": t_eval,
"Current function [A]": values["Current [A]"].data,
"Voltage [V]": corrupt_values,
}
)

# Generate problem, cost function, and optimisation class
problem = pybop.FittingProblem(model, parameters, dataset)
Expand Down
13 changes: 8 additions & 5 deletions examples/scripts/spm_IRPropMin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
values = model.predict(t_eval=t_eval)
corrupt_values = values["Voltage [V]"].data + np.random.normal(0, sigma, len(t_eval))

dataset = [
pybop.Dataset("Time [s]", t_eval),
pybop.Dataset("Current function [A]", values["Current [A]"].data),
pybop.Dataset("Voltage [V]", corrupt_values),
]
# Form dataset
dataset = pybop.Dataset(
{
"Time [s]": t_eval,
"Current function [A]": values["Current [A]"].data,
"Voltage [V]": corrupt_values,
}
)

# Generate problem, cost function, and optimisation class
problem = pybop.FittingProblem(model, parameters, dataset)
Expand Down
12 changes: 7 additions & 5 deletions examples/scripts/spm_SNES.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
values = model.predict(t_eval=t_eval)
corrupt_values = values["Voltage [V]"].data + np.random.normal(0, sigma, len(t_eval))

dataset = [
pybop.Dataset("Time [s]", t_eval),
pybop.Dataset("Current function [A]", values["Current [A]"].data),
pybop.Dataset("Voltage [V]", corrupt_values),
]
dataset = pybop.Dataset(
{
"Time [s]": t_eval,
"Current function [A]": values["Current [A]"].data,
"Voltage [V]": corrupt_values,
}
)

# Generate problem, cost function, and optimisation class
problem = pybop.FittingProblem(model, parameters, dataset)
Expand Down
13 changes: 8 additions & 5 deletions examples/scripts/spm_XNES.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
values = model.predict(t_eval=t_eval)
corrupt_values = values["Voltage [V]"].data + np.random.normal(0, sigma, len(t_eval))

dataset = [
pybop.Dataset("Time [s]", t_eval),
pybop.Dataset("Current function [A]", values["Current [A]"].data),
pybop.Dataset("Voltage [V]", corrupt_values),
]
# Form dataset
dataset = pybop.Dataset(
{
"Time [s]": t_eval,
"Current function [A]": values["Current [A]"].data,
"Voltage [V]": corrupt_values,
}
)

# Generate problem, cost function, and optimisation class
problem = pybop.FittingProblem(model, parameters, dataset)
Expand Down
14 changes: 8 additions & 6 deletions examples/scripts/spm_adam.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
values = model.predict(t_eval=t_eval)
corrupt_values = values["Voltage [V]"].data + np.random.normal(0, sigma, len(t_eval))

# Dataset definition
dataset = [
pybop.Dataset("Time [s]", t_eval),
pybop.Dataset("Current function [A]", values["Current [A]"].data),
pybop.Dataset("Voltage [V]", corrupt_values),
]
# Form dataset
dataset = pybop.Dataset(
{
"Time [s]": t_eval,
"Current function [A]": values["Current [A]"].data,
"Voltage [V]": corrupt_values,
}
)

# Generate problem, cost function, and optimisation class
problem = pybop.FittingProblem(model, parameters, dataset)
Expand Down
14 changes: 8 additions & 6 deletions examples/scripts/spm_descent.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
values = model.predict(t_eval=t_eval)
corrupt_values = values["Voltage [V]"].data + np.random.normal(0, sigma, len(t_eval))

# Dataset definition
dataset = [
pybop.Dataset("Time [s]", t_eval),
pybop.Dataset("Current function [A]", values["Current [A]"].data),
pybop.Dataset("Voltage [V]", corrupt_values),
]
# Form dataset
dataset = pybop.Dataset(
{
"Time [s]": t_eval,
"Current function [A]": values["Current [A]"].data,
"Voltage [V]": corrupt_values,
}
)

# Generate problem, cost function, and optimisation class
problem = pybop.FittingProblem(model, parameters, dataset)
Expand Down
14 changes: 8 additions & 6 deletions examples/scripts/spm_nlopt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@

# Form dataset
Measurements = pd.read_csv("examples/scripts/Chen_example.csv", comment="#").to_numpy()
dataset = [
pybop.Dataset("Time [s]", Measurements[:, 0]),
pybop.Dataset("Current function [A]", Measurements[:, 1]),
pybop.Dataset("Voltage [V]", Measurements[:, 2]),
]
dataset = pybop.Dataset(
{
"Time [s]": Measurements[:, 0],
"Current function [A]": Measurements[:, 1],
"Voltage [V]": Measurements[:, 2],
}
)

# Define model
parameter_set = pybop.ParameterSet.pybamm("Chen2020")
Expand All @@ -30,7 +32,7 @@
]

# Define the cost to optimise
signal = "Voltage [V]"
signal = ["Voltage [V]"]
problem = pybop.FittingProblem(model, parameters, dataset, signal=signal, init_soc=0.98)
cost = pybop.RootMeanSquaredError(problem)

Expand Down
13 changes: 8 additions & 5 deletions examples/scripts/spm_pso.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
values = model.predict(t_eval=t_eval)
corrupt_values = values["Voltage [V]"].data + np.random.normal(0, sigma, len(t_eval))

dataset = [
pybop.Dataset("Time [s]", t_eval),
pybop.Dataset("Current function [A]", values["Current [A]"].data),
pybop.Dataset("Voltage [V]", corrupt_values),
]
# Form dataset
dataset = pybop.Dataset(
{
"Time [s]": t_eval,
"Current function [A]": values["Current [A]"].data,
"Voltage [V]": corrupt_values,
}
)

# Generate problem, cost function, and optimisation class
problem = pybop.FittingProblem(model, parameters, dataset)
Expand Down
14 changes: 8 additions & 6 deletions examples/scripts/spm_scipymin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@

# Form dataset
Measurements = pd.read_csv("examples/scripts/Chen_example.csv", comment="#").to_numpy()
dataset = [
pybop.Dataset("Time [s]", Measurements[:, 0]),
pybop.Dataset("Current function [A]", Measurements[:, 1]),
pybop.Dataset("Voltage [V]", Measurements[:, 2]),
]
dataset = pybop.Dataset(
{
"Time [s]": Measurements[:, 0],
"Current function [A]": Measurements[:, 1],
"Voltage [V]": Measurements[:, 2],
}
)

# Define model
parameter_set = pybop.ParameterSet.pybamm("Chen2020")
Expand All @@ -30,7 +32,7 @@
]

# Define the cost to optimise
signal = "Voltage [V]"
signal = ["Voltage [V]"]
problem = pybop.FittingProblem(model, parameters, dataset, signal=signal, init_soc=0.98)
cost = pybop.RootMeanSquaredError(problem)

Expand Down
18 changes: 10 additions & 8 deletions pybop/_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,22 @@ class Dataset:
"""

def __init__(self, name, data):
def __init__(self, data_dictionary):
"""
Initialize a Dataset instance with a name and data.
Parameters
----------
name : str
The name for the dataset.
data : array-like
data_dictionary : dict or instance of pybamm.solvers.solution.Solution
The experimental data to store within the dataset.
"""

self.name = name
self.data = data
if isinstance(data_dictionary, pybamm.solvers.solution.Solution):
data_dictionary = data_dictionary.get_data_dict()
if not isinstance(data_dictionary, dict):
raise ValueError("The input to pybop.Dataset must be a dictionary.")
self.data = data_dictionary
self.names = self.data.keys()

def __repr__(self):
"""
Expand All @@ -40,9 +42,9 @@ def __repr__(self):
Returns
-------
str
A string that includes the name and data of the dataset.
A string that includes the type and contents of the dataset.
"""
return f"Dataset: {self.name} \n Data: {self.data}"
return f"Dataset: {type(self.data)} \n Contains: {self.names}"

def Interpolant(self):
"""
Expand Down
Loading

0 comments on commit 14881c3

Please sign in to comment.