deepsensor 0.3.6__tar.gz → 0.3.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {deepsensor-0.3.6 → deepsensor-0.3.8}/PKG-INFO +14 -11
  2. {deepsensor-0.3.6 → deepsensor-0.3.8}/README.md +12 -9
  3. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/active_learning/acquisition_fns.py +1 -1
  4. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/active_learning/algorithms.py +126 -76
  5. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/data/loader.py +1 -1
  6. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/data/processor.py +21 -26
  7. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/data/sources.py +47 -21
  8. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/data/task.py +9 -15
  9. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/model/convnp.py +93 -12
  10. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/model/model.py +2 -2
  11. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/plot.py +9 -4
  12. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor.egg-info/PKG-INFO +14 -11
  13. {deepsensor-0.3.6 → deepsensor-0.3.8}/setup.cfg +2 -2
  14. {deepsensor-0.3.6 → deepsensor-0.3.8}/tests/test_active_learning.py +41 -20
  15. {deepsensor-0.3.6 → deepsensor-0.3.8}/tests/test_model.py +81 -50
  16. {deepsensor-0.3.6 → deepsensor-0.3.8}/tests/test_plotting.py +11 -10
  17. {deepsensor-0.3.6 → deepsensor-0.3.8}/tests/test_task.py +10 -9
  18. {deepsensor-0.3.6 → deepsensor-0.3.8}/tests/test_task_loader.py +5 -5
  19. {deepsensor-0.3.6 → deepsensor-0.3.8}/tests/test_training.py +6 -5
  20. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/__init__.py +0 -0
  21. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/active_learning/__init__.py +0 -0
  22. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/config.py +0 -0
  23. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/data/__init__.py +0 -0
  24. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/data/utils.py +0 -0
  25. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/errors.py +0 -0
  26. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/model/__init__.py +0 -0
  27. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/model/defaults.py +0 -0
  28. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/model/nps.py +0 -0
  29. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/model/pred.py +0 -0
  30. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/py.typed +0 -0
  31. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/tensorflow/__init__.py +0 -0
  32. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/torch/__init__.py +0 -0
  33. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/train/__init__.py +0 -0
  34. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor/train/train.py +0 -0
  35. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor.egg-info/SOURCES.txt +0 -0
  36. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor.egg-info/dependency_links.txt +0 -0
  37. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor.egg-info/not-zip-safe +0 -0
  38. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor.egg-info/requires.txt +0 -0
  39. {deepsensor-0.3.6 → deepsensor-0.3.8}/deepsensor.egg-info/top_level.txt +0 -0
  40. {deepsensor-0.3.6 → deepsensor-0.3.8}/pyproject.toml +0 -0
  41. {deepsensor-0.3.6 → deepsensor-0.3.8}/setup.py +0 -0
  42. {deepsensor-0.3.6 → deepsensor-0.3.8}/tests/__init__.py +0 -0
  43. {deepsensor-0.3.6 → deepsensor-0.3.8}/tests/test_data_processor.py +0 -0
  44. {deepsensor-0.3.6 → deepsensor-0.3.8}/tests/utils.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: deepsensor
3
- Version: 0.3.6
3
+ Version: 0.3.8
4
4
  Summary: A Python package for modelling xarray and pandas data with neural processes.
5
- Home-page: https://github.com/tom-andersson/deepsensor
5
+ Home-page: https://github.com/alan-turing-institute/deepsensor
6
6
  Author: Tom R. Andersson
7
7
  Author-email: tomandersson3@gmail.com
8
8
  License: MIT
@@ -44,7 +44,7 @@ data with neural processes</p>
44
44
 
45
45
  -----------
46
46
 
47
- [![release](https://img.shields.io/badge/release-v0.3.6-green?logo=github)](https://github.com/alan-turing-institute/deepsensor/releases)
47
+ [![release](https://img.shields.io/badge/release-v0.3.8-green?logo=github)](https://github.com/alan-turing-institute/deepsensor/releases)
48
48
  [![Latest Docs](https://img.shields.io/badge/docs-latest-blue.svg)](https://alan-turing-institute.github.io/deepsensor/)
49
49
  ![Tests](https://github.com/alan-turing-institute/deepsensor/actions/workflows/tests.yml/badge.svg)
50
50
  [![Coverage Status](https://coveralls.io/repos/github/alan-turing-institute/deepsensor/badge.svg?branch=main)](https://coveralls.io/github/alan-turing-institute/deepsensor?branch=main)
@@ -62,8 +62,7 @@ This allows DeepSensor users to focus on the science and rapidly iterate on idea
62
62
 
63
63
  DeepSensor is an experimental package, and we
64
64
  welcome [contributions from the community](https://github.com/alan-turing-institute/deepsensor/blob/main/CONTRIBUTING.md).
65
- We have an active Slack channel for code and research discussions; you can request to
66
- join [via this Google Form](https://docs.google.com/forms/d/e/1FAIpQLScsI8EiXDdSfn1huMp1vj5JAxi9NIeYLljbEUlMceZvwVpugw/viewform).
65
+ We have an active Slack channel for code and research discussions; you can join by [signing up for the Turing Environment & Sustainability stakeholder community](https://forms.office.com/pages/responsepage.aspx?id=p_SVQ1XklU-Knx-672OE-ZmEJNLHTHVFkqQ97AaCfn9UMTZKT1IwTVhJRE82UjUzMVE2MThSOU5RMC4u). The form includes a question on signing up for the Slack team, where you can find DeepSensor's channel.
67
66
 
68
67
  ![DeepSensor example application figures](https://raw.githubusercontent.com/alan-turing-institute/deepsensor/main/figs/deepsensor_application_examples.png)
69
68
 
@@ -146,7 +145,7 @@ ds = data_processor(ds_raw)
146
145
  # Set up task loader
147
146
  task_loader = TaskLoader(context=ds, target=ds)
148
147
 
149
- # Set up model
148
+ # Set up ConvNP, which by default instantiates a ConvCNP with Gaussian marginals
150
149
  model = ConvNP(data_processor, task_loader)
151
150
 
152
151
  # Generate training tasks with up 100 grid cells as context and all grid cells
@@ -214,7 +213,7 @@ time lat lon
214
213
 
215
214
  DeepSensor offers far more functionality than this simple example demonstrates.
216
215
  For more information on the package's capabilities, check out the
217
- [User Guide](https://tom-andersson.github.io/deepsensor/user-guide/index.html)
216
+ [User Guide](https://alan-turing-institute.github.io/deepsensor/user-guide/index.html)
218
217
  in the documentation.
219
218
 
220
219
  ## Citing DeepSensor
@@ -231,8 +230,8 @@ DeepSensor is funded by [The Alan Turing Institute](https://www.turing.ac.uk/) u
231
230
 
232
231
  We appreciate all contributions to DeepSensor, big or small, code-related or not, and we thank all
233
232
  contributors below for supporting open-source software and research.
234
- For code-specific contributions, check out our graph of [code contributions](https://github.com/tom-andersson/deepsensor/graphs/contributors).
235
- See our [contribution guidelines](https://github.com/tom-andersson/deepsensor/blob/main/CONTRIBUTING.md)
233
+ For code-specific contributions, check out our graph of [code contributions](https://github.com/alan-turing-institute/deepsensor/graphs/contributors).
234
+ See our [contribution guidelines](https://github.com/alan-turing-institute/deepsensor/blob/main/CONTRIBUTING.md)
236
235
  if you would like to join this list!
237
236
 
238
237
  <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
@@ -243,18 +242,22 @@ if you would like to join this list!
243
242
  <tr>
244
243
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/acocac"><img src="https://avatars.githubusercontent.com/u/13321552?v=4?s=100" width="100px;" alt="Alejandro ©"/><br /><sub><b>Alejandro ©</b></sub></a><br /><a href="#userTesting-acocac" title="User Testing">📓</a> <a href="#bug-acocac" title="Bug reports">🐛</a> <a href="#mentoring-acocac" title="Mentoring">🧑‍🏫</a> <a href="#ideas-acocac" title="Ideas, Planning, & Feedback">🤔</a> <a href="#research-acocac" title="Research">🔬</a></td>
245
244
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/annavaughan"><img src="https://avatars.githubusercontent.com/u/45528489?v=4?s=100" width="100px;" alt="Anna Vaughan"/><br /><sub><b>Anna Vaughan</b></sub></a><br /><a href="#research-annavaughan" title="Research">🔬</a></td>
245
+ <td align="center" valign="top" width="14.28%"><a href="http://davidwilby.dev"><img src="https://avatars.githubusercontent.com/u/24752124?v=4?s=100" width="100px;" alt="David Wilby"/><br /><sub><b>David Wilby</b></sub></a><br /><a href="#doc-davidwilby" title="Documentation">📖</a> <a href="#test-davidwilby" title="Tests">⚠️</a> <a href="#maintenance-davidwilby" title="Maintenance">🚧</a></td>
246
+ <td align="center" valign="top" width="14.28%"><a href="http://inconsistentrecords.co.uk"><img src="https://avatars.githubusercontent.com/u/731727?v=4?s=100" width="100px;" alt="Jim Circadian"/><br /><sub><b>Jim Circadian</b></sub></a><br /><a href="#ideas-JimCircadian" title="Ideas, Planning, & Feedback">🤔</a> <a href="#projectManagement-JimCircadian" title="Project Management">📆</a> <a href="#maintenance-JimCircadian" title="Maintenance">🚧</a></td>
246
247
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/jonas-scholz123"><img src="https://avatars.githubusercontent.com/u/37850411?v=4?s=100" width="100px;" alt="Jonas Scholz"/><br /><sub><b>Jonas Scholz</b></sub></a><br /><a href="#userTesting-jonas-scholz123" title="User Testing">📓</a> <a href="#research-jonas-scholz123" title="Research">🔬</a> <a href="#code-jonas-scholz123" title="Code">💻</a> <a href="#bug-jonas-scholz123" title="Bug reports">🐛</a> <a href="#ideas-jonas-scholz123" title="Ideas, Planning, & Feedback">🤔</a></td>
247
248
  <td align="center" valign="top" width="14.28%"><a href="http://www.westerling.nu"><img src="https://avatars.githubusercontent.com/u/7298727?v=4?s=100" width="100px;" alt="Kalle Westerling"/><br /><sub><b>Kalle Westerling</b></sub></a><br /><a href="#doc-kallewesterling" title="Documentation">📖</a> <a href="#infra-kallewesterling" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#ideas-kallewesterling" title="Ideas, Planning, & Feedback">🤔</a> <a href="#projectManagement-kallewesterling" title="Project Management">📆</a> <a href="#promotion-kallewesterling" title="Promotion">📣</a> <a href="#question-kallewesterling" title="Answering Questions">💬</a></td>
248
249
  <td align="center" valign="top" width="14.28%"><a href="http://kenzaxtazi.github.io"><img src="https://avatars.githubusercontent.com/u/43008274?v=4?s=100" width="100px;" alt="Kenza Tazi"/><br /><sub><b>Kenza Tazi</b></sub></a><br /><a href="#ideas-kenzaxtazi" title="Ideas, Planning, & Feedback">🤔</a></td>
249
- <td align="center" valign="top" width="14.28%"><a href="http://magnusross.github.io/about"><img src="https://avatars.githubusercontent.com/u/51709759?v=4?s=100" width="100px;" alt="Magnus Ross"/><br /><sub><b>Magnus Ross</b></sub></a><br /><a href="#tutorial-magnusross" title="Tutorials">✅</a> <a href="#data-magnusross" title="Data">🔣</a></td>
250
- <td align="center" valign="top" width="14.28%"><a href="https://nilsleh.info/"><img src="https://avatars.githubusercontent.com/u/35272119?v=4?s=100" width="100px;" alt="Nils Lehmann"/><br /><sub><b>Nils Lehmann</b></sub></a><br /><a href="#ideas-nilsleh" title="Ideas, Planning, & Feedback">🤔</a> <a href="#userTesting-nilsleh" title="User Testing">📓</a> <a href="#bug-nilsleh" title="Bug reports">🐛</a></td>
251
250
  </tr>
252
251
  <tr>
252
+ <td align="center" valign="top" width="14.28%"><a href="http://magnusross.github.io/about"><img src="https://avatars.githubusercontent.com/u/51709759?v=4?s=100" width="100px;" alt="Magnus Ross"/><br /><sub><b>Magnus Ross</b></sub></a><br /><a href="#tutorial-magnusross" title="Tutorials">✅</a> <a href="#data-magnusross" title="Data">🔣</a></td>
253
+ <td align="center" valign="top" width="14.28%"><a href="https://nilsleh.info/"><img src="https://avatars.githubusercontent.com/u/35272119?v=4?s=100" width="100px;" alt="Nils Lehmann"/><br /><sub><b>Nils Lehmann</b></sub></a><br /><a href="#ideas-nilsleh" title="Ideas, Planning, & Feedback">🤔</a> <a href="#userTesting-nilsleh" title="User Testing">📓</a> <a href="#bug-nilsleh" title="Bug reports">🐛</a></td>
253
254
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/polpel"><img src="https://avatars.githubusercontent.com/u/56694450?v=4?s=100" width="100px;" alt="Paolo Pelucchi"/><br /><sub><b>Paolo Pelucchi</b></sub></a><br /><a href="#userTesting-polpel" title="User Testing">📓</a> <a href="#bug-polpel" title="Bug reports">🐛</a></td>
254
255
  <td align="center" valign="top" width="14.28%"><a href="https://rohitrathore.netlify.app/"><img src="https://avatars.githubusercontent.com/u/42641738?v=4?s=100" width="100px;" alt="Rohit Singh Rathaur"/><br /><sub><b>Rohit Singh Rathaur</b></sub></a><br /><a href="#code-RohitRathore1" title="Code">💻</a></td>
255
256
  <td align="center" valign="top" width="14.28%"><a href="https://scotthosking.com"><img src="https://avatars.githubusercontent.com/u/10783052?v=4?s=100" width="100px;" alt="Scott Hosking"/><br /><sub><b>Scott Hosking</b></sub></a><br /><a href="#fundingFinding-scotthosking" title="Funding Finding">🔍</a> <a href="#ideas-scotthosking" title="Ideas, Planning, & Feedback">🤔</a> <a href="#projectManagement-scotthosking" title="Project Management">📆</a></td>
256
257
  <td align="center" valign="top" width="14.28%"><a href="https://www.bas.ac.uk/profile/tomand"><img src="https://avatars.githubusercontent.com/u/26459412?v=4?s=100" width="100px;" alt="Tom Andersson"/><br /><sub><b>Tom Andersson</b></sub></a><br /><a href="#code-tom-andersson" title="Code">💻</a> <a href="#research-tom-andersson" title="Research">🔬</a> <a href="#maintenance-tom-andersson" title="Maintenance">🚧</a> <a href="#bug-tom-andersson" title="Bug reports">🐛</a> <a href="#test-tom-andersson" title="Tests">⚠️</a> <a href="#tutorial-tom-andersson" title="Tutorials">✅</a> <a href="#doc-tom-andersson" title="Documentation">📖</a> <a href="#review-tom-andersson" title="Reviewed Pull Requests">👀</a> <a href="#talk-tom-andersson" title="Talks">📢</a> <a href="#question-tom-andersson" title="Answering Questions">💬</a></td>
257
258
  <td align="center" valign="top" width="14.28%"><a href="http://wessel.ai"><img src="https://avatars.githubusercontent.com/u/1444448?v=4?s=100" width="100px;" alt="Wessel"/><br /><sub><b>Wessel</b></sub></a><br /><a href="#research-wesselb" title="Research">🔬</a> <a href="#code-wesselb" title="Code">💻</a> <a href="#ideas-wesselb" title="Ideas, Planning, & Feedback">🤔</a></td>
259
+ </tr>
260
+ <tr>
258
261
  <td align="center" valign="top" width="14.28%"><a href="http://patel-zeel.github.io"><img src="https://avatars.githubusercontent.com/u/59758528?v=4?s=100" width="100px;" alt="Zeel B Patel"/><br /><sub><b>Zeel B Patel</b></sub></a><br /><a href="#bug-patel-zeel" title="Bug reports">🐛</a> <a href="#code-patel-zeel" title="Code">💻</a> <a href="#userTesting-patel-zeel" title="User Testing">📓</a> <a href="#ideas-patel-zeel" title="Ideas, Planning, & Feedback">🤔</a></td>
259
262
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/ots22"><img src="https://avatars.githubusercontent.com/u/5434836?v=4?s=100" width="100px;" alt="ots22"/><br /><sub><b>ots22</b></sub></a><br /><a href="#ideas-ots22" title="Ideas, Planning, & Feedback">🤔</a></td>
260
263
  </tr>
@@ -11,7 +11,7 @@ data with neural processes</p>
11
11
 
12
12
  -----------
13
13
 
14
- [![release](https://img.shields.io/badge/release-v0.3.6-green?logo=github)](https://github.com/alan-turing-institute/deepsensor/releases)
14
+ [![release](https://img.shields.io/badge/release-v0.3.8-green?logo=github)](https://github.com/alan-turing-institute/deepsensor/releases)
15
15
  [![Latest Docs](https://img.shields.io/badge/docs-latest-blue.svg)](https://alan-turing-institute.github.io/deepsensor/)
16
16
  ![Tests](https://github.com/alan-turing-institute/deepsensor/actions/workflows/tests.yml/badge.svg)
17
17
  [![Coverage Status](https://coveralls.io/repos/github/alan-turing-institute/deepsensor/badge.svg?branch=main)](https://coveralls.io/github/alan-turing-institute/deepsensor?branch=main)
@@ -29,8 +29,7 @@ This allows DeepSensor users to focus on the science and rapidly iterate on idea
29
29
 
30
30
  DeepSensor is an experimental package, and we
31
31
  welcome [contributions from the community](https://github.com/alan-turing-institute/deepsensor/blob/main/CONTRIBUTING.md).
32
- We have an active Slack channel for code and research discussions; you can request to
33
- join [via this Google Form](https://docs.google.com/forms/d/e/1FAIpQLScsI8EiXDdSfn1huMp1vj5JAxi9NIeYLljbEUlMceZvwVpugw/viewform).
32
+ We have an active Slack channel for code and research discussions; you can join by [signing up for the Turing Environment & Sustainability stakeholder community](https://forms.office.com/pages/responsepage.aspx?id=p_SVQ1XklU-Knx-672OE-ZmEJNLHTHVFkqQ97AaCfn9UMTZKT1IwTVhJRE82UjUzMVE2MThSOU5RMC4u). The form includes a question on signing up for the Slack team, where you can find DeepSensor's channel.
34
33
 
35
34
  ![DeepSensor example application figures](https://raw.githubusercontent.com/alan-turing-institute/deepsensor/main/figs/deepsensor_application_examples.png)
36
35
 
@@ -113,7 +112,7 @@ ds = data_processor(ds_raw)
113
112
  # Set up task loader
114
113
  task_loader = TaskLoader(context=ds, target=ds)
115
114
 
116
- # Set up model
115
+ # Set up ConvNP, which by default instantiates a ConvCNP with Gaussian marginals
117
116
  model = ConvNP(data_processor, task_loader)
118
117
 
119
118
  # Generate training tasks with up 100 grid cells as context and all grid cells
@@ -181,7 +180,7 @@ time lat lon
181
180
 
182
181
  DeepSensor offers far more functionality than this simple example demonstrates.
183
182
  For more information on the package's capabilities, check out the
184
- [User Guide](https://tom-andersson.github.io/deepsensor/user-guide/index.html)
183
+ [User Guide](https://alan-turing-institute.github.io/deepsensor/user-guide/index.html)
185
184
  in the documentation.
186
185
 
187
186
  ## Citing DeepSensor
@@ -198,8 +197,8 @@ DeepSensor is funded by [The Alan Turing Institute](https://www.turing.ac.uk/) u
198
197
 
199
198
  We appreciate all contributions to DeepSensor, big or small, code-related or not, and we thank all
200
199
  contributors below for supporting open-source software and research.
201
- For code-specific contributions, check out our graph of [code contributions](https://github.com/tom-andersson/deepsensor/graphs/contributors).
202
- See our [contribution guidelines](https://github.com/tom-andersson/deepsensor/blob/main/CONTRIBUTING.md)
200
+ For code-specific contributions, check out our graph of [code contributions](https://github.com/alan-turing-institute/deepsensor/graphs/contributors).
201
+ See our [contribution guidelines](https://github.com/alan-turing-institute/deepsensor/blob/main/CONTRIBUTING.md)
203
202
  if you would like to join this list!
204
203
 
205
204
  <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
@@ -210,18 +209,22 @@ if you would like to join this list!
210
209
  <tr>
211
210
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/acocac"><img src="https://avatars.githubusercontent.com/u/13321552?v=4?s=100" width="100px;" alt="Alejandro ©"/><br /><sub><b>Alejandro ©</b></sub></a><br /><a href="#userTesting-acocac" title="User Testing">📓</a> <a href="#bug-acocac" title="Bug reports">🐛</a> <a href="#mentoring-acocac" title="Mentoring">🧑‍🏫</a> <a href="#ideas-acocac" title="Ideas, Planning, & Feedback">🤔</a> <a href="#research-acocac" title="Research">🔬</a></td>
212
211
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/annavaughan"><img src="https://avatars.githubusercontent.com/u/45528489?v=4?s=100" width="100px;" alt="Anna Vaughan"/><br /><sub><b>Anna Vaughan</b></sub></a><br /><a href="#research-annavaughan" title="Research">🔬</a></td>
212
+ <td align="center" valign="top" width="14.28%"><a href="http://davidwilby.dev"><img src="https://avatars.githubusercontent.com/u/24752124?v=4?s=100" width="100px;" alt="David Wilby"/><br /><sub><b>David Wilby</b></sub></a><br /><a href="#doc-davidwilby" title="Documentation">📖</a> <a href="#test-davidwilby" title="Tests">⚠️</a> <a href="#maintenance-davidwilby" title="Maintenance">🚧</a></td>
213
+ <td align="center" valign="top" width="14.28%"><a href="http://inconsistentrecords.co.uk"><img src="https://avatars.githubusercontent.com/u/731727?v=4?s=100" width="100px;" alt="Jim Circadian"/><br /><sub><b>Jim Circadian</b></sub></a><br /><a href="#ideas-JimCircadian" title="Ideas, Planning, & Feedback">🤔</a> <a href="#projectManagement-JimCircadian" title="Project Management">📆</a> <a href="#maintenance-JimCircadian" title="Maintenance">🚧</a></td>
213
214
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/jonas-scholz123"><img src="https://avatars.githubusercontent.com/u/37850411?v=4?s=100" width="100px;" alt="Jonas Scholz"/><br /><sub><b>Jonas Scholz</b></sub></a><br /><a href="#userTesting-jonas-scholz123" title="User Testing">📓</a> <a href="#research-jonas-scholz123" title="Research">🔬</a> <a href="#code-jonas-scholz123" title="Code">💻</a> <a href="#bug-jonas-scholz123" title="Bug reports">🐛</a> <a href="#ideas-jonas-scholz123" title="Ideas, Planning, & Feedback">🤔</a></td>
214
215
  <td align="center" valign="top" width="14.28%"><a href="http://www.westerling.nu"><img src="https://avatars.githubusercontent.com/u/7298727?v=4?s=100" width="100px;" alt="Kalle Westerling"/><br /><sub><b>Kalle Westerling</b></sub></a><br /><a href="#doc-kallewesterling" title="Documentation">📖</a> <a href="#infra-kallewesterling" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#ideas-kallewesterling" title="Ideas, Planning, & Feedback">🤔</a> <a href="#projectManagement-kallewesterling" title="Project Management">📆</a> <a href="#promotion-kallewesterling" title="Promotion">📣</a> <a href="#question-kallewesterling" title="Answering Questions">💬</a></td>
215
216
  <td align="center" valign="top" width="14.28%"><a href="http://kenzaxtazi.github.io"><img src="https://avatars.githubusercontent.com/u/43008274?v=4?s=100" width="100px;" alt="Kenza Tazi"/><br /><sub><b>Kenza Tazi</b></sub></a><br /><a href="#ideas-kenzaxtazi" title="Ideas, Planning, & Feedback">🤔</a></td>
216
- <td align="center" valign="top" width="14.28%"><a href="http://magnusross.github.io/about"><img src="https://avatars.githubusercontent.com/u/51709759?v=4?s=100" width="100px;" alt="Magnus Ross"/><br /><sub><b>Magnus Ross</b></sub></a><br /><a href="#tutorial-magnusross" title="Tutorials">✅</a> <a href="#data-magnusross" title="Data">🔣</a></td>
217
- <td align="center" valign="top" width="14.28%"><a href="https://nilsleh.info/"><img src="https://avatars.githubusercontent.com/u/35272119?v=4?s=100" width="100px;" alt="Nils Lehmann"/><br /><sub><b>Nils Lehmann</b></sub></a><br /><a href="#ideas-nilsleh" title="Ideas, Planning, & Feedback">🤔</a> <a href="#userTesting-nilsleh" title="User Testing">📓</a> <a href="#bug-nilsleh" title="Bug reports">🐛</a></td>
218
217
  </tr>
219
218
  <tr>
219
+ <td align="center" valign="top" width="14.28%"><a href="http://magnusross.github.io/about"><img src="https://avatars.githubusercontent.com/u/51709759?v=4?s=100" width="100px;" alt="Magnus Ross"/><br /><sub><b>Magnus Ross</b></sub></a><br /><a href="#tutorial-magnusross" title="Tutorials">✅</a> <a href="#data-magnusross" title="Data">🔣</a></td>
220
+ <td align="center" valign="top" width="14.28%"><a href="https://nilsleh.info/"><img src="https://avatars.githubusercontent.com/u/35272119?v=4?s=100" width="100px;" alt="Nils Lehmann"/><br /><sub><b>Nils Lehmann</b></sub></a><br /><a href="#ideas-nilsleh" title="Ideas, Planning, & Feedback">🤔</a> <a href="#userTesting-nilsleh" title="User Testing">📓</a> <a href="#bug-nilsleh" title="Bug reports">🐛</a></td>
220
221
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/polpel"><img src="https://avatars.githubusercontent.com/u/56694450?v=4?s=100" width="100px;" alt="Paolo Pelucchi"/><br /><sub><b>Paolo Pelucchi</b></sub></a><br /><a href="#userTesting-polpel" title="User Testing">📓</a> <a href="#bug-polpel" title="Bug reports">🐛</a></td>
221
222
  <td align="center" valign="top" width="14.28%"><a href="https://rohitrathore.netlify.app/"><img src="https://avatars.githubusercontent.com/u/42641738?v=4?s=100" width="100px;" alt="Rohit Singh Rathaur"/><br /><sub><b>Rohit Singh Rathaur</b></sub></a><br /><a href="#code-RohitRathore1" title="Code">💻</a></td>
222
223
  <td align="center" valign="top" width="14.28%"><a href="https://scotthosking.com"><img src="https://avatars.githubusercontent.com/u/10783052?v=4?s=100" width="100px;" alt="Scott Hosking"/><br /><sub><b>Scott Hosking</b></sub></a><br /><a href="#fundingFinding-scotthosking" title="Funding Finding">🔍</a> <a href="#ideas-scotthosking" title="Ideas, Planning, & Feedback">🤔</a> <a href="#projectManagement-scotthosking" title="Project Management">📆</a></td>
223
224
  <td align="center" valign="top" width="14.28%"><a href="https://www.bas.ac.uk/profile/tomand"><img src="https://avatars.githubusercontent.com/u/26459412?v=4?s=100" width="100px;" alt="Tom Andersson"/><br /><sub><b>Tom Andersson</b></sub></a><br /><a href="#code-tom-andersson" title="Code">💻</a> <a href="#research-tom-andersson" title="Research">🔬</a> <a href="#maintenance-tom-andersson" title="Maintenance">🚧</a> <a href="#bug-tom-andersson" title="Bug reports">🐛</a> <a href="#test-tom-andersson" title="Tests">⚠️</a> <a href="#tutorial-tom-andersson" title="Tutorials">✅</a> <a href="#doc-tom-andersson" title="Documentation">📖</a> <a href="#review-tom-andersson" title="Reviewed Pull Requests">👀</a> <a href="#talk-tom-andersson" title="Talks">📢</a> <a href="#question-tom-andersson" title="Answering Questions">💬</a></td>
224
225
  <td align="center" valign="top" width="14.28%"><a href="http://wessel.ai"><img src="https://avatars.githubusercontent.com/u/1444448?v=4?s=100" width="100px;" alt="Wessel"/><br /><sub><b>Wessel</b></sub></a><br /><a href="#research-wesselb" title="Research">🔬</a> <a href="#code-wesselb" title="Code">💻</a> <a href="#ideas-wesselb" title="Ideas, Planning, & Feedback">🤔</a></td>
226
+ </tr>
227
+ <tr>
225
228
  <td align="center" valign="top" width="14.28%"><a href="http://patel-zeel.github.io"><img src="https://avatars.githubusercontent.com/u/59758528?v=4?s=100" width="100px;" alt="Zeel B Patel"/><br /><sub><b>Zeel B Patel</b></sub></a><br /><a href="#bug-patel-zeel" title="Bug reports">🐛</a> <a href="#code-patel-zeel" title="Code">💻</a> <a href="#userTesting-patel-zeel" title="User Testing">📓</a> <a href="#ideas-patel-zeel" title="Ideas, Planning, & Feedback">🤔</a></td>
226
229
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/ots22"><img src="https://avatars.githubusercontent.com/u/5434836?v=4?s=100" width="100px;" alt="ots22"/><br /><sub><b>ots22</b></sub></a><br /><a href="#ideas-ots22" title="Ideas, Planning, & Feedback">🤔</a></td>
227
230
  </tr>
@@ -31,7 +31,7 @@ class AcquisitionFunction:
31
31
  context_set_idx (int):
32
32
  Index of context set to add new observations to when computing
33
33
  the acquisition function.
34
- target_set_idx (int):
34
+ target_set_idx (int):
35
35
  Index of target set to compute acquisition function for.
36
36
  """
37
37
  self.model = model
@@ -28,42 +28,99 @@ from typing import Union, List, Tuple, Optional
28
28
 
29
29
 
30
30
  class GreedyAlgorithm:
31
- """Greedy algorithm for active learning
31
+ """Greedy active learning sensor placement algorithm.
32
+
33
+ Given a set of :class:`~.data.task.Task` objects containing existing context data, the algorithm
34
+ iteratively (i.e. 'greedily') proposes $N$ locations for new context points
35
+ from a search grid, using active learning with a DeepSensorModel.
36
+
37
+ Within each greedy iteration, the algorithm evaluates an acquisition function
38
+ over the search grid. The acquisition function value at a given query location
39
+ relates to the merit of a new observation at that point, and is averaged over
40
+ all :class:`~.data.task.Task` objects. The algorithm then
41
+ selects the context location with the 'best' (max or min) acquisition function value.
42
+ A new context observation is added to each :class:`~.data.task.Task` at that location.
43
+ This process is repeated until $N$ new context locations have been proposed.
44
+
45
+ The algorithm either computes the acquisition function values
46
+ in parallel over all query locations, or sequentially. This is dictated by the
47
+ type of acquisition function passed to the algorithm:
48
+
49
+ 1. :class:`~.active_learning.acquisition_fns.AcquisitionFunction`:
50
+ Returns a scalar acquisition function for
51
+ a given query location. For example, the model's mean standard deviation
52
+ over target locations (``MeanStddev``). For a given :class:`~.data.task.Task`
53
+ this requires running the model *once for every query location* with a new
54
+ context point at that location, so these acquisition functions can be slow.
55
+
56
+ 2. :class:`~.active_learning.acquisition_fns.AcquisitionFunctionParallel`:
57
+ Returns all acquisition function values in parallel.
58
+ For example, the model's standard deviation at query locations given
59
+ the existing context data, which only requires running the model once for a
60
+ given :class:`~.data.task.Task`. These acquisition functions are faster than
61
+ their sequential counterparts but are likely less informative.
62
+
63
+ Acquisition functions that inherit from
64
+ :class:`~.active_learning.acquisition_fns.AcquisitionFunctionOracle`
65
+ require ground truth target values at target locations. In this case, the algorithm
66
+ must be provided with a :class:`~.data.loader.TaskLoader` object to sample these values.
67
+
68
+ .. note::
69
+ The algorithm is described in more detail in 'Environmental Sensor Placement with
70
+ Convolutional Gaussian Neural Processes' (2023), https://doi.org/10.1017/eds.2023.22.
32
71
 
33
72
  Args:
34
73
  model (:class:`~.model.model.DeepSensorModel`):
35
- Trained model to use for proposing new context points.
36
- X_s (:class:`xarray.Dataset` | :class:`xarray.DataArray` | :class:`pandas.DataFrame` | :class:`pandas.Series` | :class:`pandas.Index`):
37
- Search coordinates.
38
- X_t (:class:`xarray.Dataset` | :class:`xarray.DataArray`):
39
- Target coordinates.
74
+ Model to use for proposing new context points.
75
+ X_s (:class:`xarray.Dataset` | :class:`xarray.DataArray`):
76
+ Xarray object containing the spatial coordinates that define the search grid.
77
+ X_t (:class:`xarray.Dataset` | :class:`xarray.DataArray` | pd.DataFrame):
78
+ Target spatial coordinates. Can either be an xarray object containing the spatial
79
+ coordinates of the target grid, or a pandas DataFrame containing a set of off-grid
80
+ target locations.
40
81
  X_s_mask (:class:`xarray.Dataset` | :class:`xarray.DataArray`, optional):
41
- Mask for search coordinates. If provided, only points where mask
42
- is True will be considered. Defaults to None.
82
+ Optional 2D mask for gridded search coordinates to ignore. If provided, the acquisition
83
+ function will only be computed at locations where the mask is True. Defaults to None.
43
84
  X_t_mask (:class:`xarray.Dataset` | :class:`xarray.DataArray`, optional):
44
- [Description of the X_t_mask parameter.], defaults to None.
85
+ Optional 2D mask (for gridded target coordinates) to ignore.
86
+ Useful e.g. if you only care about improving the model's predictions over a certain
87
+ area. Defaults to None.
45
88
  N_new_context (int, optional):
46
- [Description of the N_new_context parameter.], defaults to 1.
89
+ Number of new context points to propose (i.e. number of greedy iterations), defaults to 1.
47
90
  X_normalised (bool, optional):
48
- [Description of the X_normalised parameter.], defaults to False.
91
+ Whether the coordinates of the X_* arguments above have been normalised
92
+ by a :class:`~.data.processor.DataProcessor`. Defaults to False.
49
93
  model_infill_method (str, optional):
50
- [Description of the model_infill_method parameter.], defaults to "mean".
94
+ Method for generating pseudo observations from the model at search points,
95
+ which are appended to Tasks when computing acquisition functions or at the
96
+ end of a greedy iteration (unless overridden by ``query_infill`` or ``proposed_infill`` below).
97
+ Currently, only "mean" infilling is supported. Defaults to "mean".
51
98
  query_infill (:class:`xarray.DataArray`, optional):
52
- [Description of the query_infill parameter.], defaults to None.
99
+ Gridded xarray object containing observations to use when querying candidate context
100
+ points. Must have all the same time points as the :class:`~.data.task.Task` objects
101
+ the algorithm is called with. If not on the same grid as ``X_s``, it will be linearly
102
+ interpolated to the same grid. Useful for providing the model with true observations
103
+ rather than its own predictions. Defaults to None.
53
104
  proposed_infill (:class:`xarray.DataArray`, optional):
54
- [Description of the proposed_infill parameter.], defaults to None.
105
+ Similar to ``query_infill``, but used when infilling pseudo observations at the end
106
+ of a greedy iteration (rather than using model predictions). Useful e.g. to
107
+ simulate the case where the model can obtain ground truth after requesting
108
+ a sensor placement. Defaults to None.
55
109
  context_set_idx (int, optional):
56
- [Description of the context_set_idx parameter.], defaults to 0.
110
+ Context set index to run the sensor placement algorithm on. E.g. if a model
111
+ ingest two context sets ["aux_data", "sensor_data"], this should be set to 1
112
+ (corresponding to the sensor context set). Defaults to 0.
57
113
  target_set_idx (int, optional):
58
- [Description of the target_set_idx parameter.], defaults to 0.
114
+ Target set index corresponding to predictions of the context set that the
115
+ algorithm is run on. Defaults to 0.
59
116
  progress_bar (bool, optional):
60
- [Description of the progress_bar parameter.], defaults to False.
61
- min_or_max (str, optional):
62
- [Description of the min_or_max parameter.], defaults to "min".
117
+ Whether to display a progress bar when running the algorithm. Defaults to False.
63
118
  task_loader (:class:`~.data.loader.TaskLoader`, optional):
64
- [Description of the task_loader parameter.], defaults to None.
119
+ If using an :class:`~.active_learning.acquisition_fns.AcquisitionFunctionOracle`,
120
+ a TaskLoader object is required to sample ground truth target values at target
121
+ locations. Defaults to None.
65
122
  verbose (bool, optional):
66
- [Description of the verbose parameter.], defaults to False.
123
+ Whether to print some status messages. Defaults to False.
67
124
 
68
125
  Raises:
69
126
  ValueError:
@@ -74,8 +131,8 @@ class GreedyAlgorithm:
74
131
  def __init__(
75
132
  self,
76
133
  model: DeepSensorModel,
77
- X_s: Union[xr.Dataset, xr.DataArray, pd.DataFrame, pd.Series, pd.Index],
78
- X_t: Union[xr.Dataset, xr.DataArray, pd.DataFrame, pd.Series, pd.Index],
134
+ X_s: Union[xr.Dataset, xr.DataArray],
135
+ X_t: Union[xr.Dataset, xr.DataArray, pd.DataFrame],
79
136
  X_s_mask: Optional[Union[xr.Dataset, xr.DataArray]] = None,
80
137
  X_t_mask: Optional[Union[xr.Dataset, xr.DataArray]] = None,
81
138
  N_new_context: int = 1,
@@ -198,23 +255,7 @@ class GreedyAlgorithm:
198
255
  self,
199
256
  X_s: Union[xr.Dataset, xr.DataArray, pd.DataFrame, pd.Series, pd.Index],
200
257
  ):
201
- """
202
- Computes and sets the model infill y-values over whole search grid
203
- before running greedy optimisation. Results are returned with
204
- additional first axis, with ``size > 1`` if
205
- ``model_infill_method == 'sample'`` or ``'ar_sample_*'``, and
206
- acquisition function will be averaged over the samples in the first
207
- axis. If ``model_infill_method != 'sample'``, first axis size is 1 and
208
- the averaging is only over one value (i.e. no averaging).
209
-
210
- Infilled y-values at all placement search locations are appended to
211
- each dataset with the key (`'Y_model_infilled'`) for use during the
212
- placement search.
213
-
214
- Also adds a sample dimension to the context station observations, which
215
- will be looped over for MCMC sampling of the acquisition function
216
- importance values of the placement criterion.
217
- """
258
+ """Computes and model infill y-values over whole search grid."""
218
259
  if self.model_infill_method == "mean":
219
260
  pred = self.model.predict(
220
261
  self.tasks,
@@ -225,10 +266,11 @@ class GreedyAlgorithm:
225
266
  infill_ds = pred[self.target_set_idx]["mean"]
226
267
 
227
268
  elif self.model_infill_method == "sample":
228
- # _, _, infill_ds = self.model.predict(
269
+ # pred = self.model.predict(
229
270
  # self.tasks, X_s, X_t_normalised=True, unnormalise=False,
230
271
  # n_samples=self.model_infill_samples,
231
272
  # )
273
+ # infill_ds = pred[self.target_set_idx]["samples"]
232
274
  raise NotImplementedError("TODO")
233
275
 
234
276
  elif self.model_infill_method == "zeros":
@@ -244,23 +286,22 @@ class GreedyAlgorithm:
244
286
 
245
287
  def _sample_y_infill(self, infill_ds, time, x1, x2):
246
288
  """Sample infill values at a single location"""
247
- if isinstance(infill_ds, (xr.Dataset, xr.DataArray)):
248
- y = infill_ds.sel(time=time, x1=x1, x2=x2)
249
- if isinstance(y, xr.Dataset):
250
- y = y.to_array()
251
- y = y.data
252
- y = y.reshape(1, y.size) # 1 observation with N dimensions
289
+ assert isinstance(infill_ds, (xr.Dataset, xr.DataArray))
290
+ y = infill_ds.sel(time=time, x1=x1, x2=x2)
291
+ if isinstance(y, xr.Dataset):
292
+ y = y.to_array()
293
+ y = y.data
294
+ if "sample" not in infill_ds.dims:
295
+ return y.reshape(1, y.size) # 1 observation with N_target_dims
253
296
  else:
254
- raise NotImplementedError(
255
- f"infill_ds must be xr.Dataset or xr.DataArray, "
256
- f"not {type(infill_ds)}"
257
- )
258
- return y
297
+ # TODO confirm or force that dim ordering is (N_samples, N_target_dims)
298
+ return y
259
299
 
260
300
  def _build_acquisition_fn_ds(self, X_s: Union[xr.Dataset, xr.DataArray]):
261
301
  """
262
302
  Initialise xr.DataArray for storing acquisition function values on
263
- search grid"""
303
+ search grid
304
+ """
264
305
  prepend_dims = ["iteration"] # , "sample"] # MC sample TODO
265
306
  prepend_coords = {
266
307
  "iteration": range(self.N_new_context),
@@ -278,7 +319,7 @@ class GreedyAlgorithm:
278
319
 
279
320
  return acquisition_fn_ds
280
321
 
281
- def _init_acquisition_fn_ds(self, X_s: xr.Dataset):
322
+ def _init_acquisition_fn_object(self, X_s: xr.Dataset):
282
323
  """Instantiate acquisition function object"""
283
324
  # Unnormalise before instantiating
284
325
  X_s = self.model.data_processor.map_coords(X_s, unnorm=True)
@@ -297,16 +338,6 @@ class GreedyAlgorithm:
297
338
  """
298
339
  Run one greedy pass by looping over each point in ``X_s`` and
299
340
  computing the acquisition function.
300
-
301
- If the search algorithm can be run over all points in parallel,
302
- this method should be overridden by the child class so that
303
- ``self.run()`` uses the parallel implementation.
304
-
305
- ..
306
- TODO check if below is still valid in GreedyOptimal:
307
- If the search method uses the y-values at search points (i.e. for
308
- an optimal benchmark), its ``acquisition_fn`` should expect a
309
- ``y_query`` input.
310
341
  """
311
342
  importances_list = []
312
343
 
@@ -384,7 +415,7 @@ class GreedyAlgorithm:
384
415
  return np.mean(importances_list, axis=0)
385
416
 
386
417
  def _select_best(self, importances, X_s_arr):
387
- """Select sensor location corresponding to the best importance value.
418
+ """Select context location corresponding to the best importance value.
388
419
 
389
420
  Appends the chosen search index to a list of chosen search indexes.
390
421
  """
@@ -395,7 +426,7 @@ class GreedyAlgorithm:
395
426
 
396
427
  best_x_query = X_s_arr[:, best_idx : best_idx + 1]
397
428
 
398
- # Index into original search space of chosen sensor location
429
+ # Index into original search space of chosen context location
399
430
  self.best_idxs_all.append(
400
431
  np.where((self.X_s_arr == best_x_query).all(axis=0))[0][0]
401
432
  )
@@ -405,7 +436,7 @@ class GreedyAlgorithm:
405
436
  def _single_greedy_iteration(self, acquisition_fn: AcquisitionFunction):
406
437
  """
407
438
  Run a single greedy grid search iteration and append the optimal
408
- sensor location to self.X_new.
439
+ context location to self.X_new.
409
440
  """
410
441
  importances = self._search(acquisition_fn)
411
442
  best_x_query = self._select_best(importances, self.X_s_arr)
@@ -421,17 +452,36 @@ class GreedyAlgorithm:
421
452
  diff: bool = False,
422
453
  ) -> Tuple[pd.DataFrame, xr.Dataset]:
423
454
  """
424
- Iteratively... docstring TODO
455
+ Iteratively propose new context points using the greedy sensor placement algorithm.
425
456
 
426
457
  Args:
427
458
  acquisition_fn (:class:`~.active_learning.acquisition_fns.AcquisitionFunction`):
428
- [Description of the acquisition_fn parameter.]
459
+ The acquisition function to optimise.
429
460
  tasks (List[:class:`~.data.task.Task`] | :class:`~.data.task.Task`):
430
- [Description of the tasks parameter.]
461
+ Tasks containing existing context data. If a list of Tasks, the acquisition
462
+ function will be averaged over Tasks.
463
+ diff (bool, optional):
464
+ For sequential acquisition functions only: Whether to compute the *change* in
465
+ acquisition function value after adding the new context point, i.e.
466
+ ``acquisition_fn(task_with_new) - acquisition_fn(task)``. Can be useful
467
+ for making the acquisition function values more interpretable, or for
468
+ comparing with the change in metric that the acquisition function targets
469
+ (see https://doi.org/10.1017/eds.2023.22). Defaults to False.
431
470
 
432
471
  Returns:
433
- Tuple[:class:`pandas.DataFrame`, :class:`xarray.Dataset`]:
434
- X_new_df, acquisition_fn_ds - [Description of the return values.]
472
+ Tuple[:class:`pandas.DataFrame`, :class:`xarray.DataArray`]:
473
+ A tuple containing two objects:
474
+
475
+ - **X_new_df** (:class:`pandas.DataFrame`):
476
+ Proposed sensor placements. Columns are the x1 and x2 coordinates of the
477
+ sensor placements, and the index is the index of the greedy iteration
478
+ at which the sensor placement was proposed (which can be interpreted as
479
+ a priority order, with iteration 0 being the highest priority).
480
+
481
+ - **acquisition_fn_ds** (:class:`xarray.DataArray`):
482
+ Gridded acquisition function values at each search point. Dimensions
483
+ are ``iteration``, ``time`` (inferred from the input ``tasks``), followed
484
+ by the x1 and x2 coordinates of the spatial grid.
435
485
 
436
486
  Raises:
437
487
  ValueError:
@@ -502,10 +552,10 @@ class GreedyAlgorithm:
502
552
  self.proposed_infill = model_infill
503
553
 
504
554
  # Instantiate empty acquisition function object
505
- self._init_acquisition_fn_ds(self.X_s)
555
+ self._init_acquisition_fn_object(self.X_s)
506
556
 
507
557
  # Dataframe for storing proposed context locations
508
- self.X_new_df = pd.DataFrame(columns=["x1", "x2"])
558
+ self.X_new_df = pd.DataFrame(columns=[self.x1_name, self.x2_name])
509
559
  self.X_new_df.index.name = "iteration"
510
560
 
511
561
  # List to track indexes into original search grid of chosen sensor locations
@@ -518,8 +568,8 @@ class GreedyAlgorithm:
518
568
  total_iterations = self.N_new_context * len(self.tasks)
519
569
  if not isinstance(acquisition_fn, AcquisitionFunctionParallel):
520
570
  total_iterations *= self.X_s_arr.shape[-1]
521
- # TODO make class attribute for list of sample methods
522
- if self.model_infill_method == "sample":
571
+ # TODO make class attribute for list of sample-based infill methods
572
+ if self.model_infill_method in ["sample", "ar_sample"]:
523
573
  total_iterations *= self.n_samples
524
574
 
525
575
  with tqdm(total=total_iterations, disable=not self.progress_bar) as self.pbar:
@@ -25,7 +25,7 @@ class TaskLoader:
25
25
  - If all data passed as paths, load the data and overwrite the paths with the loaded data
26
26
  - Either all data is passed as paths, or all data is passed as loaded data (else ``ValueError``)
27
27
  - If all data passed as paths, the TaskLoader can be saved with the ``save`` method
28
- (using config)
28
+ (using config)
29
29
 
30
30
  Args:
31
31
  task_loader_ID:
@@ -97,7 +97,7 @@ class DataProcessor:
97
97
  self.verbose = verbose
98
98
 
99
99
  # List of valid normalisation method names
100
- self.valid_methods = ["mean_std", "min_max"]
100
+ self.valid_methods = ["mean_std", "min_max", "positive_semidefinite"]
101
101
 
102
102
  def save(self, folder: str):
103
103
  """Save DataProcessor config to JSON in `folder`"""
@@ -293,6 +293,8 @@ class DataProcessor:
293
293
  params = {"mean": float(data.mean()), "std": float(data.std())}
294
294
  elif method == "min_max":
295
295
  params = {"min": float(data.min()), "max": float(data.max())}
296
+ elif method == "positive_semidefinite":
297
+ params = {"min": float(data.min()), "std": float(data.std())}
296
298
  if self.verbose:
297
299
  print(f"Done. {var_ID} {method} params={params}")
298
300
  self.add_to_config(
@@ -498,33 +500,25 @@ class DataProcessor:
498
500
 
499
501
  params = self.get_config(var_ID, data, method)
500
502
 
503
+ # Linear transformation:
504
+ # - Inverse normalisation: y_unnorm = m * y_norm + c
505
+ # - Inverse normalisation: y_norm = (1/m) * y_unnorm - c/m
501
506
  if method == "mean_std":
502
- std = params["std"]
503
- mean = params["mean"]
504
- if unnorm:
505
- scale = std
506
- offset = mean
507
- else:
508
- scale = 1 / std
509
- offset = -mean / std
510
- data = data * scale
511
- if add_offset:
512
- data = data + offset
513
- return data
514
-
507
+ m = params["std"]
508
+ c = params["mean"]
515
509
  elif method == "min_max":
516
- minimum = params["min"]
517
- maximum = params["max"]
518
- if unnorm:
519
- scale = (maximum - minimum) / 2
520
- offset = (maximum + minimum) / 2
521
- else:
522
- scale = 2 / (maximum - minimum)
523
- offset = -(maximum + minimum) / (maximum - minimum)
524
- data = data * scale
525
- if add_offset:
526
- data = data + offset
527
- return data
510
+ m = (params["max"] - params["min"]) / 2
511
+ c = (params["max"] + params["min"]) / 2
512
+ elif method == "positive_semidefinite":
513
+ m = params["std"]
514
+ c = params["min"]
515
+ if not unnorm:
516
+ c = -c / m
517
+ m = 1 / m
518
+ data = data * m
519
+ if add_offset:
520
+ data = data + c
521
+ return data
528
522
 
529
523
  def map(
530
524
  self,
@@ -610,6 +604,7 @@ class DataProcessor:
610
604
  method (str, optional): Normalisation method. Options include:
611
605
  - "mean_std": Normalise to mean=0 and std=1 (default)
612
606
  - "min_max": Normalise to min=-1 and max=1
607
+ - "positive_semidefinite": Normalise to min=0 and std=1
613
608
 
614
609
  Returns:
615
610
  :class:`xarray.DataArray` | :class:`xarray.Dataset` | :class:`pandas.DataFrame` | List[:class:`xarray.DataArray` | :class:`xarray.Dataset` | :class:`pandas.DataFrame`]: