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

Update plotting capabilities and dataset restructure #178

Merged
merged 85 commits into from
Mar 21, 2024
Merged
Changes from 1 commit
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
c95c8ce
Update plotting, descriptions and examples
NicolaCourtier Jan 29, 2024
c8dc7d7
style: pre-commit fixes
pre-commit-ci[bot] Jan 29, 2024
1b86e64
Update notebooks
NicolaCourtier Jan 29, 2024
dd228eb
Update notebooks
NicolaCourtier Jan 29, 2024
4b4a1f1
Update legends
NicolaCourtier Jan 29, 2024
90ddac3
Add getitem and update dataset checks
NicolaCourtier Jan 29, 2024
8c4eb77
style: pre-commit fixes
pre-commit-ci[bot] Jan 29, 2024
7c3c8e6
Update test_dataset.py
NicolaCourtier Jan 29, 2024
048ecf6
Add plotting tests
NicolaCourtier Jan 29, 2024
a0632b5
Add test_plot_dataset
NicolaCourtier Jan 29, 2024
18ba0c2
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Feb 2, 2024
e8e1268
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Feb 8, 2024
c8d6c51
Update dataset check
NicolaCourtier Feb 8, 2024
2920865
style: pre-commit fixes
pre-commit-ci[bot] Feb 8, 2024
1cdea9e
Update UKF example plotting
NicolaCourtier Feb 8, 2024
a189796
Revert file names
NicolaCourtier Feb 9, 2024
3f66b25
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Feb 9, 2024
ac10023
Re-implement change to BaseCost
NicolaCourtier Feb 9, 2024
93095b6
Separate off plot_parameters
NicolaCourtier Feb 9, 2024
bfe5bb9
style: pre-commit fixes
pre-commit-ci[bot] Feb 9, 2024
1ccfda1
Move plot_parameters in init
NicolaCourtier Feb 9, 2024
993aa91
Update spm_electrode_design.ipynb
NicolaCourtier Feb 9, 2024
541ac05
Re-implement design changes to quick_plot
NicolaCourtier Feb 9, 2024
a00a2be
Update subplot widths, test_plotting dataset access, remove square br…
BradyPlanden Feb 16, 2024
bc48170
Update pybop/plotting/plot_convergence.py
NicolaCourtier Feb 16, 2024
b5ebd42
Update pybop/plotting/plot_cost2d.py
NicolaCourtier Feb 16, 2024
6fba3ac
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Feb 16, 2024
b26ac6b
Update plot_cost2d.py
NicolaCourtier Feb 16, 2024
d3f2217
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Feb 19, 2024
452e5e8
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Feb 19, 2024
2c5fbd7
Remove duplicate getitem
NicolaCourtier Feb 19, 2024
89ec0cc
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Feb 21, 2024
89e2932
Add plotting support for notebook rendering, adds kaleido as dependancy
BradyPlanden Feb 22, 2024
f853af9
+ diffevolution notebook
BradyPlanden Feb 22, 2024
fc06f1f
Merge branch '177-plotting-capabilities' into 177b-plotting-capabilities
BradyPlanden Feb 22, 2024
d7a71a7
fix missed deletion during merge
BradyPlanden Feb 22, 2024
0bf88ce
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Feb 23, 2024
4f5dbe6
Merge branch '177-plotting-capabilities' into 177b-plotting-capabilities
BradyPlanden Feb 23, 2024
183df28
Update test_plots.py
NicolaCourtier Feb 23, 2024
ed2bf7c
Merge branch '177-plotting-capabilities' into 177b-plotting-capabilities
BradyPlanden Feb 23, 2024
a91d7a8
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Feb 29, 2024
30da2fb
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Feb 29, 2024
4cf9108
Revamp model, problem, and cost object from numpy arrays to dictionar…
BradyPlanden Mar 1, 2024
3428c97
Fix ukf examples, temporarily limits ukf to signal output model
BradyPlanden Mar 1, 2024
43521da
default_variables to additional_variables w/ docstrings, updt. observ…
BradyPlanden Mar 2, 2024
67d2887
Fix integration test logic, add gradient landscape plots, pin pytest …
BradyPlanden Mar 4, 2024
b6a073b
Add tests for gradient plots, up coverage
BradyPlanden Mar 4, 2024
ee4cdff
Set default SciPyMinimize method to Nelder-Mead, clean-up repo
BradyPlanden Mar 4, 2024
7bc6fd2
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Mar 7, 2024
66efaba
unicode fix for win notebooks, update prediction shape checks, remove…
BradyPlanden Mar 8, 2024
a76777e
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Mar 8, 2024
6c6494a
Update spm_MLE example
NicolaCourtier Mar 8, 2024
9b03734
Updt. cost2d/optim2d x0 shape/colour, revert conftest win platform un…
BradyPlanden Mar 13, 2024
e7aef79
Updt SciPy & BaseOptimiser for maximum iterations limit - fixes #237
BradyPlanden Mar 13, 2024
afd4990
add infeasible cost tests, remove redundant scipyminimise maxiter opt…
BradyPlanden Mar 13, 2024
a9ea84c
Merge pull request #224 from pybop-team/177c-plotting-capabilities
BradyPlanden Mar 13, 2024
d6a172a
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Mar 14, 2024
05c7f20
Merge branch '177-plotting-capabilities' into 177b-plotting-capabilities
BradyPlanden Mar 14, 2024
db28440
Updt grad descent hypers for likelihood tests, add tol arg to scipy o…
BradyPlanden Mar 15, 2024
61d7d7a
Split kaleido dependancy to avoid windows hang
BradyPlanden Mar 15, 2024
744d166
small refactors and cleanup
BradyPlanden Mar 15, 2024
c1b3854
Updt changelog
BradyPlanden Mar 15, 2024
f9b10e8
Merge branch 'develop' into 177-plotting-capabilities
NicolaCourtier Mar 18, 2024
716c671
updt coverage, bugfix sigma check/wrap
BradyPlanden Mar 19, 2024
41cf0f8
Merge branch '177-plotting-capabilities' into 177b-plotting-capabilities
BradyPlanden Mar 19, 2024
a479136
coverage, bugfix model.simulateS1
BradyPlanden Mar 19, 2024
691b0ae
Merge pull request #198 from pybop-team/177b-plotting-capabilities
BradyPlanden Mar 19, 2024
18a1a4e
Update to n_time_data and add two_signal test
NicolaCourtier Mar 20, 2024
19b247c
style: pre-commit fixes
pre-commit-ci[bot] Mar 20, 2024
695c2c9
Test standard plot and plot_trajectories
NicolaCourtier Mar 20, 2024
47c0058
Add test_with_ipykernel
NicolaCourtier Mar 20, 2024
1a80b6f
style: pre-commit fixes
pre-commit-ci[bot] Mar 20, 2024
fa551a0
Re-add test_with_ipykernel
NicolaCourtier Mar 20, 2024
b6ce663
Update test_plots.py
NicolaCourtier Mar 20, 2024
f198cbe
Rename plot_cost2d as plot2d
NicolaCourtier Mar 20, 2024
9ef3897
Merge plot_optim2d with plot2d
NicolaCourtier Mar 20, 2024
f42298f
Update scripts to plot2d
NicolaCourtier Mar 20, 2024
3ca404d
Update notebooks to plot2d
NicolaCourtier Mar 20, 2024
302add7
Update spm_MLE.py
NicolaCourtier Mar 20, 2024
fe090f1
Update filename to plot2d
NicolaCourtier Mar 20, 2024
7b8c7f0
Rename plot_cost2d.py to plot2d.py
NicolaCourtier Mar 20, 2024
8bfaeba
Fix typo in error message
NicolaCourtier Mar 20, 2024
cb70505
Reduce init_soc in test_model_misparameterisation
NicolaCourtier Mar 20, 2024
76b5c19
Update ipykernel print to assert
NicolaCourtier Mar 21, 2024
e513c33
Fix version check
NicolaCourtier Mar 21, 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
Prev Previous commit
Next Next commit
Updt grad descent hypers for likelihood tests, add tol arg to scipy o…
…ptimisers, pass optimiser final cost as is
BradyPlanden committed Mar 15, 2024
commit db284402100e0b1bb8c3ed0d4b6dad98f849ed8f
8 changes: 4 additions & 4 deletions pybop/_optimisation.py
Original file line number Diff line number Diff line change
@@ -156,8 +156,6 @@ def run(self):
x, final_cost = self._run_pints()
elif not self.pints:
x, final_cost = self._run_pybop()
if not self._minimising:
final_cost = -final_cost

# Store the optimised parameters
if self.cost.problem is not None:
@@ -374,8 +372,10 @@ def _run_pints(self):
# Store the optimised parameters
self.store_optimised_parameters(x)

# Return best position and score
return x, f if self._minimising else -f
# Return best position and the score used internally,
# i.e the negative log-likelihood in the case of
# self._minimising = False
return x, f

def f_guessed_tracking(self):
"""
2 changes: 1 addition & 1 deletion pybop/costs/_likelihoods.py
Original file line number Diff line number Diff line change
@@ -95,9 +95,9 @@
y, dy = self.problem.evaluateS1(x)
for key in self.signal:
if len(y.get(key, [])) != len(self._target.get(key, [])):
likelihood = np.float64(np.inf)
dl = self._de * np.ones(self.n_parameters)
dl = self._dl * np.ones(self.n_parameters)
return -likelihood, -dl

Check warning on line 100 in pybop/costs/_likelihoods.py

Codecov / codecov/patch

pybop/costs/_likelihoods.py#L98-L100

Added lines #L98 - L100 were not covered by tests

r = np.array([self._target[signal] - y[signal] for signal in self.signal])

@@ -150,7 +150,7 @@

for key in self.signal:
if len(prediction.get(key, [])) != len(self._target.get(key, [])):
return -np.float64(np.inf) # prediction doesn't match target

Check warning on line 153 in pybop/costs/_likelihoods.py

Codecov / codecov/patch

pybop/costs/_likelihoods.py#L153

Added line #L153 was not covered by tests

e = np.array(
[
@@ -167,7 +167,7 @@
if self.n_outputs == 1:
return e.item()
else:
return np.sum(e)

Check warning on line 170 in pybop/costs/_likelihoods.py

Codecov / codecov/patch

pybop/costs/_likelihoods.py#L170

Added line #L170 was not covered by tests

def _evaluateS1(self, x, grad=None):
"""
@@ -176,14 +176,14 @@
"""
sigma = np.asarray(x[-self.n_outputs :])
if np.any(sigma <= 0):
return -np.float64(np.inf), self._de * np.ones(self.n_parameters)

Check warning on line 179 in pybop/costs/_likelihoods.py

Codecov / codecov/patch

pybop/costs/_likelihoods.py#L179

Added line #L179 was not covered by tests

y, dy = self.problem.evaluateS1(x[: -self.n_outputs])
for key in self.signal:
if len(y.get(key, [])) != len(self._target.get(key, [])):
likelihood = np.float64(np.inf)
dl = self._de * np.ones(self.n_parameters)
return -likelihood, -dl

Check warning on line 186 in pybop/costs/_likelihoods.py

Codecov / codecov/patch

pybop/costs/_likelihoods.py#L184-L186

Added lines #L184 - L186 were not covered by tests

r = np.array([self._target[signal] - y[signal] for signal in self.signal])

@@ -196,9 +196,9 @@
dl = np.concatenate((dl, dsigma))
return likelihood, dl
else:
r = r.reshape(self.n_outputs, self.problem.n_time_data)

Check warning on line 199 in pybop/costs/_likelihoods.py

Codecov / codecov/patch

pybop/costs/_likelihoods.py#L199

Added line #L199 was not covered by tests
likelihood = self._evaluate(x)
dl = sigma ** (-2.0) * np.sum((r[:, :, np.newaxis] * dy), axis=1)
dsigma = -self._n_times / sigma + sigma**-(3.0) * np.sum(r**2, axis=0)

Check warning on line 202 in pybop/costs/_likelihoods.py

Codecov / codecov/patch

pybop/costs/_likelihoods.py#L201-L202

Added lines #L201 - L202 were not covered by tests
dl = np.concatenate((dl, dsigma))
return likelihood, np.sum(dl, axis=1)

Check warning on line 204 in pybop/costs/_likelihoods.py

Codecov / codecov/patch

pybop/costs/_likelihoods.py#L204

Added line #L204 was not covered by tests
10 changes: 8 additions & 2 deletions pybop/optimisers/scipy_optimisers.py
Original file line number Diff line number Diff line change
@@ -20,10 +20,11 @@ class SciPyMinimize(BaseOptimiser):
Maximum number of iterations to perform.
"""

def __init__(self, method=None, bounds=None, maxiter=None):
def __init__(self, method=None, bounds=None, maxiter=None, tol=1e-5):
super().__init__()
self.method = method
self.bounds = bounds
self.tol = tol
self.options = {}
self._max_iterations = maxiter

@@ -79,6 +80,7 @@ def cost_wrapper(x):
x0,
method=self.method,
bounds=bounds,
tol=self.tol,
options=self.options,
callback=callback,
)
@@ -126,8 +128,11 @@ class SciPyDifferentialEvolution(BaseOptimiser):
The number of individuals in the population. Defaults to 15.
"""

def __init__(self, bounds=None, strategy="best1bin", maxiter=1000, popsize=15):
def __init__(
self, bounds=None, strategy="best1bin", maxiter=1000, popsize=15, tol=1e-5
):
super().__init__()
self.tol = tol
self.strategy = strategy
self._max_iterations = maxiter
self._population_size = popsize
@@ -178,6 +183,7 @@ def callback(x, convergence):
strategy=self.strategy,
maxiter=self._max_iterations,
popsize=self._population_size,
tol=self.tol,
callback=callback,
)

12 changes: 8 additions & 4 deletions tests/integration/test_parameterisations.py
Original file line number Diff line number Diff line change
@@ -70,7 +70,7 @@ def spm_costs(self, model, parameters, cost_class, init_soc):
model, parameters, dataset, signal=signal, init_soc=init_soc
)
if cost_class in [pybop.GaussianLogLikelihoodKnownSigma]:
return cost_class(problem, sigma=[0.05, 0.05])
return cost_class(problem, sigma=[0.03, 0.03])
else:
return cost_class(problem)

@@ -123,7 +123,11 @@ def test_spm_optimisers(self, optimiser, spm_costs):
assert parameterisation._max_iterations == 125

elif optimiser in [pybop.GradientDescent]:
parameterisation.optimiser.set_learning_rate(0.02)
if isinstance(spm_costs, pybop.GaussianLogLikelihoodKnownSigma):
parameterisation.optimiser.set_learning_rate(1.8e-5)
parameterisation.set_min_iterations(150)
else:
parameterisation.optimiser.set_learning_rate(0.02)
parameterisation.set_max_iterations(150)
x, final_cost = parameterisation.run()

@@ -196,9 +200,9 @@ def test_multiple_signals(self, multi_optimiser, spm_two_signal_cost):

# Test each optimiser
parameterisation = pybop.Optimisation(
cost=spm_two_signal_cost, optimiser=multi_optimiser, sigma0=0.05
cost=spm_two_signal_cost, optimiser=multi_optimiser, sigma0=0.03
)
parameterisation.set_max_unchanged_iterations(iterations=15, threshold=5e-4)
parameterisation.set_max_unchanged_iterations(iterations=35, threshold=5e-4)
parameterisation.set_max_iterations(125)
initial_cost = parameterisation.cost(spm_two_signal_cost.x0)


Unchanged files with check annotations Beta

solution = self.problem.evaluate(initial_conditions)
if "Time [s]" not in solution:
raise ValueError("The solution does not contain time data.")

Check warning on line 62 in pybop/costs/design_costs.py

Codecov / codecov/patch

pybop/costs/design_costs.py#L62

Added line #L62 was not covered by tests
self.problem._time_data = solution["Time [s]"]
self.problem._target = {key: solution[key] for key in self.problem.signal}
self.dt = solution["Time [s]"][1] - solution["Time [s]"][0]
return np.inf
# Catch any other exception and return infinity
except Exception as e:
print(f"An error occurred during the evaluation: {e}")
return np.inf

Check warning on line 144 in pybop/costs/design_costs.py

Codecov / codecov/patch

pybop/costs/design_costs.py#L142-L144

Added lines #L142 - L144 were not covered by tests
class VolumetricEnergyDensity(DesignCost):
return np.inf
# Catch any other exception and return infinity
except Exception as e:
print(f"An error occurred during the evaluation: {e}")
return np.inf

Check warning on line 202 in pybop/costs/design_costs.py

Codecov / codecov/patch

pybop/costs/design_costs.py#L200-L202

Added lines #L200 - L202 were not covered by tests
for key in self.signal:
if len(y.get(key, [])) != len(self._target.get(key, [])):
e = np.float64(np.inf)
de = self._de * np.ones(self.n_parameters)
return e, de

Check warning on line 87 in pybop/costs/fitting_costs.py

Codecov / codecov/patch

pybop/costs/fitting_costs.py#L85-L87

Added lines #L85 - L87 were not covered by tests
r = np.array([y[signal] - self._target[signal] for signal in self.signal])
average_voltage = positive_electrode_ocp(
mean_sto_pos
) - negative_electrode_ocp(mean_sto_neg)
except TypeError:
average_voltage = positive_electrode_ocp([mean_sto_pos]).evaluate()[0][

Check warning on line 231 in pybop/models/lithium_ion/echem_base.py

Codecov / codecov/patch

pybop/models/lithium_ion/echem_base.py#L230-L231

Added lines #L230 - L231 were not covered by tests
0
] - negative_electrode_ocp(mean_sto_neg) # Super hacky, needs to be fixed
for t, v in zip(times, values[signal]):
try:
log_likelihood += self.observe(t, v)
except Exception:
return np.float64(-np.inf)

Check warning on line 110 in pybop/observers/observer.py

Codecov / codecov/patch

pybop/observers/observer.py#L109-L110

Added lines #L109 - L110 were not covered by tests
return log_likelihood
else:
raise ValueError(

Check warning on line 113 in pybop/observers/observer.py

Codecov / codecov/patch

pybop/observers/observer.py#L113

Added line #L113 was not covered by tests
"Obersever.log_likelihood is currently restricted to single output models."
)
fig = plot_dict(show=False)
fig.update_layout(**layout_kwargs)
if "ipykernel" in sys.modules and show:
fig.show("svg")

Check warning on line 54 in pybop/plotting/plot_convergence.py

Codecov / codecov/patch

pybop/plotting/plot_convergence.py#L54

Added line #L54 was not covered by tests
elif show:
fig.show()
# Update the layout and display the figure
fig.update_layout(**layout_kwargs)
if "ipykernel" in sys.modules and show:
fig.show("svg")

Check warning on line 140 in pybop/plotting/plot_convergence.py

Codecov / codecov/patch

pybop/plotting/plot_convergence.py#L140

Added line #L140 was not covered by tests
elif show:
fig.show()
fig = go.Figure(data=[go.Contour(x=x, y=y, z=costs)], layout=layout)
fig.update_layout(**layout_kwargs)
if "ipykernel" in sys.modules and show:
fig.show("svg")

Check warning on line 98 in pybop/plotting/plot_cost2d.py

Codecov / codecov/patch

pybop/plotting/plot_cost2d.py#L98

Added line #L98 was not covered by tests
elif show:
fig.show()
grad_fig.update_layout(**layout_kwargs)
if "ipykernel" in sys.modules and show:
grad_fig.show("svg")

Check warning on line 119 in pybop/plotting/plot_cost2d.py

Codecov / codecov/patch

pybop/plotting/plot_cost2d.py#L119

Added line #L119 was not covered by tests
elif show:
grad_fig.show()
)
fig.update_layout(**layout_kwargs)
if "ipykernel" in sys.modules and show:
fig.show("svg")

Check warning on line 57 in pybop/plotting/plot_dataset.py

Codecov / codecov/patch

pybop/plotting/plot_dataset.py#L57

Added line #L57 was not covered by tests
elif show:
fig.show()
fig = plot_dict(show=False)
fig.update_layout(**layout_kwargs)
if "ipykernel" in sys.modules and show:
fig.show("svg")

Check warning on line 76 in pybop/plotting/plot_parameters.py

Codecov / codecov/patch

pybop/plotting/plot_parameters.py#L76

Added line #L76 was not covered by tests
elif show:
fig.show()
# Create a plotting dictionary
if isinstance(problem, pybop.DesignProblem):
trace_name = "Optimised"
opt_time_data = model_output["Time [s]"]

Check warning on line 51 in pybop/plotting/plot_problem.py

Codecov / codecov/patch

pybop/plotting/plot_problem.py#L51

Added line #L51 was not covered by tests
else:
trace_name = "Model"
opt_time_data = xaxis_data
fig = plot_dict(show=False)
fig.update_layout(**layout_kwargs)
if "ipykernel" in sys.modules and show:
fig.show("svg")

Check warning on line 99 in pybop/plotting/plot_problem.py

Codecov / codecov/patch

pybop/plotting/plot_problem.py#L99

Added line #L99 was not covered by tests
elif show:
fig.show()
Install the Plotly package using pip. Exit if installation fails.
"""
try:
subprocess.check_call(

Check warning on line 79 in pybop/plotting/plotly_manager.py

Codecov / codecov/patch

pybop/plotting/plotly_manager.py#L79

Added line #L79 was not covered by tests
[sys.executable, "-m", "pip", "install", "plotly", "kaleido"]
)
except subprocess.CalledProcessError as e:
"""
fig = self.go.Figure(data=self.traces, layout=self.layout)
if "ipykernel" in sys.modules and show:
fig.show("svg")

Check warning on line 149 in pybop/plotting/quick_plot.py

Codecov / codecov/patch

pybop/plotting/quick_plot.py#L149

Added line #L149 was not covered by tests
elif show:
fig.show()
if start != -1 and end != -1:
char_in_brackets = s[start + 1 : end]
return s[:start] + " / " + char_in_brackets + s[end + 1 :]
return s

Check warning on line 206 in pybop/plotting/quick_plot.py

Codecov / codecov/patch

pybop/plotting/quick_plot.py#L206

Added line #L206 was not covered by tests
class StandardSubplot(StandardPlot):
fig.update_yaxes(title_text=y_title, row=row, col=col)
if "ipykernel" in sys.modules and show:
fig.show("svg")

Check warning on line 302 in pybop/plotting/quick_plot.py

Codecov / codecov/patch

pybop/plotting/quick_plot.py#L302

Added line #L302 was not covered by tests
elif show:
fig.show()
fig = plot_dict(show=False)
fig.update_layout(**layout_kwargs)
if "ipykernel" in sys.modules and show:
fig.show("svg")

Check warning on line 342 in pybop/plotting/quick_plot.py

Codecov / codecov/patch

pybop/plotting/quick_plot.py#L342

Added line #L342 was not covered by tests
elif show:
fig.show()