dapper 1.3.0__tar.gz → 1.5.0__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 (158) hide show
  1. {dapper-1.3.0 → dapper-1.5.0}/PKG-INFO +4 -8
  2. {dapper-1.3.0 → dapper-1.5.0}/README.md +64 -44
  3. dapper-1.5.0/dapper/README.md +43 -0
  4. dapper-1.5.0/dapper/__init__.py +15 -0
  5. {dapper-1.3.0 → dapper-1.5.0}/dapper/da_methods/__init__.py +21 -11
  6. {dapper-1.3.0 → dapper-1.5.0}/dapper/da_methods/baseline.py +38 -10
  7. {dapper-1.3.0 → dapper-1.5.0}/dapper/da_methods/ensemble.py +81 -88
  8. {dapper-1.3.0 → dapper-1.5.0}/dapper/da_methods/particle.py +2 -2
  9. {dapper-1.3.0 → dapper-1.5.0}/dapper/da_methods/variational.py +1 -1
  10. {dapper-1.3.0 → dapper-1.5.0}/dapper/dpr_config.py +4 -4
  11. dapper-1.5.0/dapper/mods/Id/__init__.py +42 -0
  12. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LA/__init__.py +1 -1
  13. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz05/__init__.py +3 -9
  14. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz05/settings01.py +1 -0
  15. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LorenzUV/lorenz96.py +5 -4
  16. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LorenzUV/wilks05.py +5 -4
  17. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/__init__.py +4 -2
  18. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/demo.py +21 -23
  19. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/README.md +7 -1
  20. dapper-1.5.0/dapper/mods/QG/f90/__init__.py +1 -0
  21. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/interface.f90 +2 -1
  22. dapper-1.5.0/dapper/mods/QG/f90/prms_test_model.txt +16 -0
  23. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/qgflux.f90 +13 -4
  24. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/qgstep.f90 +80 -28
  25. dapper-1.5.0/dapper/mods/QG/illust_obs.py +51 -0
  26. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/README.md +1 -1
  27. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/__init__.py +4 -3
  28. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/integration.py +12 -10
  29. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/utils.py +3 -17
  30. {dapper-1.3.0 → dapper-1.5.0}/dapper/stats.py +19 -13
  31. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/chronos.py +1 -1
  32. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/colors.py +2 -2
  33. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/datafiles.py +10 -7
  34. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/linalg.py +3 -3
  35. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/liveplotting.py +1 -10
  36. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/localization.py +19 -22
  37. dapper-1.5.0/dapper/tools/multiproc.py +73 -0
  38. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/progressbar.py +1 -1
  39. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/randvars.py +8 -8
  40. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/remote/README.md +1 -1
  41. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/remote/__init__.py +1 -1
  42. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/seeding.py +6 -7
  43. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/series.py +6 -5
  44. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/viz.py +1 -1
  45. {dapper-1.3.0 → dapper-1.5.0}/dapper/xp_launch.py +80 -41
  46. {dapper-1.3.0 → dapper-1.5.0}/dapper/xp_process.py +43 -34
  47. {dapper-1.3.0 → dapper-1.5.0}/dapper.egg-info/PKG-INFO +4 -8
  48. {dapper-1.3.0 → dapper-1.5.0}/dapper.egg-info/SOURCES.txt +5 -1
  49. {dapper-1.3.0 → dapper-1.5.0}/dapper.egg-info/requires.txt +20 -12
  50. {dapper-1.3.0 → dapper-1.5.0}/examples/basic_1.py +4 -5
  51. {dapper-1.3.0 → dapper-1.5.0}/examples/basic_2.py +20 -14
  52. {dapper-1.3.0 → dapper-1.5.0}/pyproject.toml +29 -18
  53. {dapper-1.3.0 → dapper-1.5.0}/setup.py +14 -13
  54. {dapper-1.3.0 → dapper-1.5.0}/tests/test_HMMs.py +7 -0
  55. {dapper-1.3.0 → dapper-1.5.0}/tests/test_data.py +0 -3
  56. {dapper-1.3.0 → dapper-1.5.0}/tests/test_example_2.py +48 -32
  57. dapper-1.5.0/tests/test_operator.py +51 -0
  58. {dapper-1.3.0 → dapper-1.5.0}/tests/test_printing.py +2 -22
  59. dapper-1.5.0/tests/test_randvars.py +15 -0
  60. dapper-1.3.0/dapper/README.md +0 -72
  61. dapper-1.3.0/dapper/__init__.py +0 -33
  62. dapper-1.3.0/dapper/mods/QG/f90/__init__.py +0 -3
  63. dapper-1.3.0/dapper/tools/magic.py +0 -171
  64. dapper-1.3.0/dapper/tools/multiproc.py +0 -85
  65. {dapper-1.3.0 → dapper-1.5.0}/LICENCE.txt +0 -0
  66. {dapper-1.3.0 → dapper-1.5.0}/dapper/da_methods/README.md +0 -0
  67. {dapper-1.3.0 → dapper-1.5.0}/dapper/da_methods/extended.py +0 -0
  68. {dapper-1.3.0 → dapper-1.5.0}/dapper/da_methods/other.py +0 -0
  69. {dapper-1.3.0 → dapper-1.5.0}/dapper/dpr_config.yaml +0 -0
  70. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/DoublePendulum/__init__.py +0 -0
  71. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/DoublePendulum/demo.py +0 -0
  72. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/DoublePendulum/settings101.py +0 -0
  73. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Ikeda/__init__.py +0 -0
  74. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Ikeda/demo.py +0 -0
  75. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Ikeda/some_settings_01.py +0 -0
  76. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/KS/__init__.py +0 -0
  77. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/KS/bocquet2019.py +0 -0
  78. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/KS/compare_schemes.py +0 -0
  79. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/KS/demo.py +0 -0
  80. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LA/demo.py +0 -0
  81. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LA/evensen2009.py +0 -0
  82. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LA/raanes2015.py +0 -0
  83. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LA/small.py +0 -0
  84. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz05/demo.py +0 -0
  85. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz63/__init__.py +0 -0
  86. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz63/anderson2010rhf.py +0 -0
  87. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz63/bocquet2012.py +0 -0
  88. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz63/demo.py +0 -0
  89. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz63/extras.py +0 -0
  90. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz63/mandel2016.py +0 -0
  91. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz63/sakov2012.py +0 -0
  92. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz63/wiljes2017.py +0 -0
  93. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz84/__init__.py +0 -0
  94. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz84/demo.py +0 -0
  95. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz84/harder.py +0 -0
  96. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz84/pajonk2012.py +0 -0
  97. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/__init__.py +0 -0
  98. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/anderson2009.py +0 -0
  99. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/bocquet2010.py +0 -0
  100. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/bocquet2010_m40.py +0 -0
  101. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/bocquet2015loc.py +0 -0
  102. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/demo.py +0 -0
  103. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/extras.py +0 -0
  104. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/frei2013bridging.py +0 -0
  105. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/hoteit2015.py +0 -0
  106. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/miyoshi2011.py +0 -0
  107. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/pinheiro2019.py +0 -0
  108. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/raanes2016.py +0 -0
  109. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/sakov2008.py +0 -0
  110. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/spectral_obs.py +0 -0
  111. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/todter2015.py +0 -0
  112. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96/todter2015_G.py +0 -0
  113. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96s/__init__.py +0 -0
  114. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/Lorenz96s/grudzien2020.py +0 -0
  115. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LorenzUV/__init__.py +0 -0
  116. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LorenzUV/demo.py +0 -0
  117. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LorenzUV/illust_LorenzUV.py +0 -0
  118. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LorenzUV/illust_parameterizations.py +0 -0
  119. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LotkaVolterra/__init__.py +0 -0
  120. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LotkaVolterra/demo.py +0 -0
  121. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/LotkaVolterra/settings101.py +0 -0
  122. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/counillon2009.py +0 -0
  123. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/Makefile +0 -0
  124. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/calc.f90 +0 -0
  125. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/data.f90 +0 -0
  126. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/helmholtz.f90 +0 -0
  127. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/nfw.f90 +0 -0
  128. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/parameters.f90 +0 -0
  129. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/prms_cou09_ens.txt +0 -0
  130. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/prms_cou09_truth.txt +0 -0
  131. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/prms_counillon2009_ens.txt +0 -0
  132. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/prms_counillon2009_truth.txt +0 -0
  133. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/prms_sak08.txt +0 -0
  134. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/prms_sakov2008.txt +0 -0
  135. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/prms_sample_generation.txt +0 -0
  136. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/qg.f90 +0 -0
  137. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/f90/utils.f90 +0 -0
  138. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/governing_eqn.png +0 -0
  139. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/QG/sakov2008.py +0 -0
  140. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/VL20/__init__.py +0 -0
  141. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/VL20/demo.py +0 -0
  142. {dapper-1.3.0 → dapper-1.5.0}/dapper/mods/explore_props.py +0 -0
  143. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/__init__.py +0 -0
  144. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/matrices.py +0 -0
  145. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/remote/autoscaler.py +0 -0
  146. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/remote/uplink.py +0 -0
  147. {dapper-1.3.0 → dapper-1.5.0}/dapper/tools/rounding.py +0 -0
  148. {dapper-1.3.0 → dapper-1.5.0}/dapper.egg-info/dependency_links.txt +0 -0
  149. {dapper-1.3.0 → dapper-1.5.0}/dapper.egg-info/top_level.txt +0 -0
  150. {dapper-1.3.0 → dapper-1.5.0}/setup.cfg +0 -0
  151. {dapper-1.3.0 → dapper-1.5.0}/tests/__init__.py +0 -0
  152. {dapper-1.3.0 → dapper-1.5.0}/tests/test_TLMs.py +0 -0
  153. {dapper-1.3.0 → dapper-1.5.0}/tests/test_demos.py +0 -0
  154. {dapper-1.3.0 → dapper-1.5.0}/tests/test_iEnKS.py +0 -0
  155. {dapper-1.3.0 → dapper-1.5.0}/tests/test_localization.py +0 -0
  156. {dapper-1.3.0 → dapper-1.5.0}/tests/test_matrices.py +0 -0
  157. {dapper-1.3.0 → dapper-1.5.0}/tests/test_plotting.py +0 -0
  158. {dapper-1.3.0 → dapper-1.5.0}/tests/test_round2.py +0 -0
@@ -1,33 +1,29 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dapper
3
- Version: 1.3.0
3
+ Version: 1.5.0
4
4
  Summary: DAPPER benchmarks the performance of data assimilation (DA) methods.
5
- Home-page: UNKNOWN
6
5
  Author: Patrick N. Raanes
7
6
  Author-email: patrick.n.raanes@gmail.com
8
- License: UNKNOWN
9
7
  Project-URL: Documentation, https://nansencenter.github.io/DAPPER/
10
8
  Project-URL: Source, https://github.com/nansencenter/DAPPER
11
9
  Project-URL: Tracker, https://github.com/nansencenter/DAPPER/issues
12
10
  Keywords: data-assimilation enkf kalman-filtering state-estimation particle-filter kalman bayesian-methods bayesian-filter chaos
13
- Platform: UNKNOWN
14
11
  Classifier: Development Status :: 3 - Alpha
15
12
  Classifier: Intended Audience :: Science/Research
16
13
  Classifier: Topic :: Scientific/Engineering :: Mathematics
17
14
  Classifier: Programming Language :: Python :: 3
18
15
  Classifier: License :: OSI Approved :: MIT License
19
16
  Classifier: Operating System :: OS Independent
20
- Requires-Python: >=3.7
17
+ Requires-Python: >=3.9
21
18
  Description-Content-Type: text/markdown
22
19
  Provides-Extra: Qt
23
- Provides-Extra: dev
20
+ Provides-Extra: debug
24
21
  Provides-Extra: test
25
22
  Provides-Extra: lint
26
23
  Provides-Extra: build
24
+ Provides-Extra: dev
27
25
  License-File: LICENCE.txt
28
26
 
29
27
  It is usually best to install from source (github),
30
28
  so that you the code is readily available to play with.
31
29
  See full README on [github](https://github.com/nansencenter/DAPPER).
32
-
33
-
@@ -20,7 +20,7 @@ and use these to generate a synthetic truth (multivariate time series),
20
20
  and then estimate that truth given the models and noisy observations.
21
21
 
22
22
  <!-- Badges / shields -->
23
- [![Github CI](https://img.shields.io/github/workflow/status/nansencenter/DAPPER/superintendent?logo=github&style=for-the-badge)](https://github.com/nansencenter/DAPPER/actions)
23
+ [![Github CI](https://img.shields.io/github/actions/workflow/status/nansencenter/DAPPER/tests.yml?branch=master&logo=github&style=for-the-badge)](https://github.com/nansencenter/DAPPER/actions)
24
24
  [![Coveralls](https://img.shields.io/coveralls/github/nansencenter/DAPPER?style=for-the-badge&logo=coveralls)](https://coveralls.io/github/nansencenter/DAPPER?branch=master)
25
25
  [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?style=for-the-badge&logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
26
26
  [![PyPI - Version](https://img.shields.io/pypi/v/dapper.svg?style=for-the-badge&logo=pypi&logoColor=white)](https://pypi.python.org/pypi/dapper/)
@@ -28,7 +28,7 @@ and then estimate that truth given the models and noisy observations.
28
28
 
29
29
  ## Getting started
30
30
 
31
- [Install](#Installation), then
31
+ [Install](#installation), then
32
32
  read, run and try to understand `examples/basic_{1,2,3}.py`.
33
33
  Some of the examples can also be opened in Jupyter, and thereby run in the cloud
34
34
  (i.e. *without installation*, but requiring Google login): [![Open In Collab](https://colab.research.google.com/assets/colab-badge.svg)](http://colab.research.google.com/github/nansencenter/DAPPER).
@@ -46,35 +46,52 @@ see these [tutorials](https://github.com/nansencenter/DA-tutorials).
46
46
 
47
47
  ## Highlights
48
48
 
49
- DAPPER enables the numerical investigation of [DA methods](#DA-methods)
50
- through a variety of typical [test cases](#Test-cases-models) and statistics. It
49
+ DAPPER enables the numerical investigation of [DA methods](#da-methods)
50
+ through a variety of typical [test cases](#test-cases-models) and statistics. It
51
51
  (a) reproduces numerical benchmarks results reported in the literature, and
52
52
  (b) facilitates comparative studies, thus promoting the
53
53
  (a) reliability and
54
54
  (b) relevance of the results.
55
- For example, this figure is generated by `examples/basic_3.py` and is a
56
- reproduction of figure 5.7 of [these lecture notes](http://cerea.enpc.fr/HomePages/bocquet/teaching/assim-mb-en.pdf).
55
+ For example, this figure is generated by `examples/basic_3.py`,
56
+ making use of built-in tools for experiment and result management,
57
+ reproduces figure 5.7 of [these lecture notes](http://cerea.enpc.fr/HomePages/bocquet/teaching/assim-mb-en.pdf).
57
58
 
58
59
  ![Comparative benchmarks with Lorenz'96 plotted as a function of the ensemble size (N)](./docs/imgs/ex3.svg)
59
60
 
60
61
  DAPPER is (c) open source, written in Python, and (d) focuses on readability;
61
62
  this promotes the (c) reproduction and (d) dissemination of the underlying science,
62
63
  and makes it easy to adapt and extend.
63
- It also comes with a battery of diagnostics and statistics,
64
- and live plotting (on-line with the assimilation) facilities,
65
- including pause/inspect options, as illustrated below
64
+
65
+ It also illustrates how to parallelise ensemble forecasts (e.g. the QG model),
66
+ local analyses (e.g. the LETKF), and independent experiments (e.g. `examples/basic_3.py`).
67
+ It comes with a battery of diagnostics and statistics.
68
+ These all get averaged over subdomains (e..g "ocean" and "land") and then in time.
69
+ Confidence intervals are computed, including correction for auto-correlations,
70
+ and used for uncertainty quantification, and significant digits printing.
71
+ Several diagnostics are included in the on-line "liveplotting" illustrated below,
72
+ which may be paused for further interactive inspection.
66
73
 
67
74
  ![EnKF - Lorenz'63](./docs/imgs/ex1.jpg)
68
75
 
69
- In summary, it is well suited for teaching and fundamental DA research.
76
+ <!-- Non-highlighted features:
77
+ - Time sequences use via `tools.chronos.Chronology` and `tools.chronos.Ticker`.
78
+ - Random variables via `tools.randvars.RV`: Gaussian, Student-t, Laplace, Uniform,
79
+ ..., as well as support for custom sampling functions.
80
+ - Covariance matrices via `tools.matrices.CovMat`:
81
+ provides input flexibility/overloading,
82
+ lazy eval that facilitates the use of non-diagonal
83
+ covariance matrices (whether sparse or full).
84
+ -->
85
+
86
+ In summary, DAPPER is well suited for teaching and fundamental DA research.
70
87
  Also see its [drawbacks](#similar-projects).
71
88
 
72
89
 
73
90
  ## Installation
74
91
 
75
- Works on Linux/Windows/Mac.
92
+ Successfully tested on Linux/Mac/Windows.
76
93
 
77
- ### Prerequisite: Python>=3.7
94
+ ### Prerequisite: Python>=3.9
78
95
 
79
96
  If you're an expert, setup a python environment however you like.
80
97
  Otherwise:
@@ -83,12 +100,12 @@ open the [Anaconda terminal](https://docs.conda.io/projects/conda/en/latest/user
83
100
  and run the following commands:
84
101
 
85
102
  ```sh
86
- conda create --yes --name dapper-env python=3.8
103
+ conda create --yes --name dapper-env python=3.9
87
104
  conda activate dapper-env
88
105
  python --version
89
106
  ```
90
107
 
91
- Ensure the printed version is 3.7 or more.
108
+ Ensure the printed version is 3.9 or more.
92
109
  *Keep using the same terminal for the commands below.*
93
110
 
94
111
  ### Install
@@ -101,7 +118,7 @@ Ensure the printed version is 3.7 or more.
101
118
  - Move the resulting folder wherever you like,
102
119
  and `cd` into it
103
120
  *(ensure you're in the folder with a `setup.py` file)*.
104
- - `pip install -e .[dev]`
121
+ - `pip install -e '.[dev]'`
105
122
  You can omit `[dev]` if you don't need to do serious development.
106
123
 
107
124
  #### *Or*: Install as library
@@ -170,6 +187,7 @@ grep -r "xp.*iEnKS" dapper/mods
170
187
 
171
188
  Model | Lin | TLM** | PDE? | Phys.dim. | State len | Lyap≥0 | Implementer
172
189
  ----------- | --- | ----- | ---- | --------- | --------- | ------ | ----------
190
+ Id | Yes | Yes | No | N/A | * | 0 | Raanes
173
191
  Linear Advect. (LA) | Yes | Yes | Yes | 1d | 1000 * | 51 | Evensen/Raanes
174
192
  DoublePendulum | No | Yes | No | 0d | 4 | 2 | Matplotlib/Raanes
175
193
  Ikeda | No | Yes | No | 0d | 2 | 1 | Raanes
@@ -205,7 +223,7 @@ Some files contain settings used by several papers.
205
223
  Moreover, at the bottom of each such file should be (in comments)
206
224
  a list of suitable, tuned settings for various DA methods,
207
225
  along with their expected, average `rmse.a` score for that experiment.
208
- As mentioned [above](#DA-methods), DAPPER reproduces literature results.
226
+ As mentioned [above](#da-methods), DAPPER reproduces literature results.
209
227
  You will also find results that were not reproduced by DAPPER.
210
228
 
211
229
 
@@ -216,7 +234,7 @@ Example of limitations:
216
234
 
217
235
  - It is not suited for very big models (>60k unknowns).
218
236
  - Time-dependent error covariances and changes in lengths of state/obs
219
- (although the Dyn and Obs models may otherwise be time-dependent).
237
+ (although the `Dyn` and `Obs` models may otherwise be time-dependent).
220
238
  - Non-uniform time sequences not fully supported.
221
239
 
222
240
  The scope of DAPPER is restricted because
@@ -251,23 +269,24 @@ Name | Developers | Purpose (approximately)
251
269
  Below is a list of projects with a purpose more similar to DAPPER's
252
270
  (research *in* DA, and not so much *using* DA):
253
271
 
254
- Name | Developers | Notes
255
- ------------------------------------ | ---------------------- | ---------------------------------
256
- [DAPPER][22] | Raanes, Chen, Grudzien | Python
257
- [SANGOMA][5] | Conglomerate* | Fortran, Matlab
258
- [hIPPYlib][25] | Villa, Petra, Ghattas | Python, adjoint-based PDE methods
259
- [FilterPy][12] | R. Labbe | Python. Engineering oriented.
260
- [DASoftware][13] | Yue Li, Stanford | Matlab. Large inverse probs.
261
- [Pomp][18] | U of Michigan | R
262
- [EnKF-Matlab][15] | Sakov | Matlab
263
- [EnKF-C][17] | Sakov | C. Light-weight, off-line DA
264
- [pyda][16] | Hickman | Python
265
- [PyDA][19] | Shady-Ahmed | Python
266
- [DasPy][20] | Xujun Han | Python
267
- [DataAssim.jl][23] | Alexander-Barth | Julia
268
- [DataAssimilationBenchmarks.jl][24] | Grudzien | Julia, Python
269
- Datum | Raanes | Matlab
270
- IEnKS code | Bocquet | Python
272
+ Name | Developers | Notes
273
+ ------------------------------------ | ---------------------- | ---------------------------------
274
+ [DAPPER][22] | Raanes, Chen, Grudzien | Python
275
+ [SANGOMA][5] | Conglomerate* | Fortran, Matlab
276
+ [hIPPYlib][25] | Villa, Petra, Ghattas | Python, adjoint-based PDE methods
277
+ [FilterPy][12] | R. Labbe | Python. Engineering oriented.
278
+ [DASoftware][13] | Yue Li, Stanford | Matlab. Large inverse probs.
279
+ [Pomp][18] | U of Michigan | R
280
+ [EnKF-Matlab][15] | Sakov | Matlab
281
+ [EnKF-C][17] | Sakov | C. Light-weight, off-line DA
282
+ [pyda][16] | Hickman | Python
283
+ [PyDA][19] | Shady-Ahmed | Python
284
+ [DasPy][20] | Xujun Han | Python
285
+ [DataAssim.jl][23] | Alexander-Barth | Julia
286
+ [DataAssimilationBenchmarks.jl][24] | Grudzien | Julia, Python
287
+ [EnsembleKalmanProcesses.jl][26] | Clim. Modl. Alliance | Julia, EKI (optim)
288
+ Datum | Raanes | Matlab
289
+ IEnKS code | Bocquet | Python
271
290
 
272
291
  The `EnKF-Matlab` and `IEnKS` codes have been inspirational
273
292
  in the development of DAPPER.
@@ -294,11 +313,12 @@ in the development of DAPPER.
294
313
  [18]: https://github.com/kingaa/pomp
295
314
  [19]: https://github.com/Shady-Ahmed/PyDA
296
315
  [20]: https://github.com/daspy/daspy
297
- [21]: https://www.jcsda.noaa.gov/index.php
316
+ [21]: https://jointcenterforsatellitedataassimilation-jedi-docs.readthedocs-hosted.com/en/latest/
298
317
  [22]: https://github.com/nansencenter/DAPPER
299
318
  [23]: https://juliahub.com/docs/DataAssim/qCDwD/0.3.2/
300
319
  [24]: https://github.com/cgrudz/DataAssimilationBenchmarks.jl
301
320
  [25]: https://hippylib.github.io/
321
+ [26]: https://github.com/CliMA/EnsembleKalmanProcesses.jl
302
322
 
303
323
 
304
324
  ## Contributors
@@ -314,24 +334,24 @@ NORCE (Norwegian Research Institute)
314
334
  and the Nansen Environmental and Remote Sensing Center (NERSC),
315
335
  in collaboration with the University of Reading,
316
336
  the UK National Centre for Earth Observation (NCEO),
317
- and the University of Nevada, Reno.
337
+ and the Center for Western Weather and Water Extremes (CW3E).
318
338
 
319
339
  <!-- markdownlint-capture -->
320
340
  <!-- markdownlint-disable line-length -->
321
341
  ![NORCE](./docs/imgs/norce-logo.png)
322
342
  ![NERSC](./docs/imgs/nansen-logo.png)
323
- <img src="https://github.com/nansencenter/DAPPER/blob/master/docs/imgs/UoR-logo.png?raw=true" height="140" />
324
- <img src="https://github.com/nansencenter/DAPPER/blob/master/docs/imgs/nceologo1000.png?raw=true" width="400">
325
- <img src="./docs/imgs/UNR_logo.png?raw=true" width="400">
343
+ <img src="https://github.com/nansencenter/DAPPER/blob/master/docs/imgs/UoR-logo.png?raw=true" height="120" />
344
+ <img src="https://github.com/nansencenter/DAPPER/blob/master/docs/imgs/nceologo1000.png?raw=true" height="100">
345
+ <img src="./docs/imgs/CW3E-Logo-Horizontal-FullColor.png?raw=true" width="400">
326
346
  <!-- markdownlint-restore -->
327
347
 
328
348
  ## Publication list
329
349
 
330
- - <https://www.geosci-model-dev-discuss.net/gmd-2019-136/>
331
- - <https://rmets.onlinelibrary.wiley.com/doi/abs/10.1002/qj.3386>
332
- - <https://www.nonlin-processes-geophys-discuss.net/npg-2019-10>
333
- - <https://link.springer.com/article/10.1007/s11004-021-09937-x>
334
- - <https://arxiv.org/abs/2010.07063>
350
+ - [Combining data assimilation and machine learning to emulate a dynamical model from sparse and noisy observations: A case study with the Lorenz 96 model](https://doi.org/10.1016/j.jocs.2020.101171)
351
+ - [Adaptive covariance inflation in the ensemble Kalman filter by Gaussian scale mixtures](https://doi.org/10.1002/qj.3386)
352
+ - [Revising the stochastic iterative ensemble smoother](https://doi.org/10.5194/npg-26-325-2019)
353
+ - [p-Kernel Stein Variational Gradient Descent for Data Assimilation and History Matching](https://doi.org/10.1007/s11004-021-09937-x)
354
+ - [Springer book chapter: Data Assimilation for Chaotic Dynamics](https://doi.org/10.1007/978-3-030-77722-7_1)
335
355
 
336
356
 
337
357
  <!-- markdownlint-configure-file
@@ -0,0 +1,43 @@
1
+ ## API reference
2
+
3
+ Click the links in the navigation menu to view
4
+ the docs for the various modules.
5
+
6
+ ## Installation
7
+
8
+ See [README/Installation](https://github.com/nansencenter/DAPPER#Installation)
9
+
10
+ ## Usage
11
+
12
+ See [README/Getting-started](https://github.com/nansencenter/DAPPER#Getting-started)
13
+
14
+ ##### Examples
15
+
16
+ See [examples/README](https://github.com/nansencenter/DAPPER/tree/master/examples)
17
+
18
+ ##### Adding your own model/method
19
+
20
+ If you wish to illustrate and run benchmarks with
21
+ your own **model** or **method**, then
22
+
23
+ - If it is a complex one, you may be better off using DAPPER
24
+ merely as *inspiration* (but you can still
25
+ [cite it](https://github.com/nansencenter/DAPPER#getting-started))
26
+ rather than trying to squeeze everything into its templates.
27
+ - If it is relatively simple, however, you may well want to use DAPPER.
28
+ In that case, read this:
29
+ - `mods`
30
+ - `da_methods`
31
+
32
+ Since the generality of DAPPER is
33
+ [limited](https://github.com/nansencenter/DAPPER#similar-projects)
34
+ it is quite likely you will also need to make changes to the DAPPER code itself.
35
+
36
+ ## Developer guide
37
+
38
+ If you are making a pull request, please read the [developer guide](dev_guide).
39
+
40
+ ## Bibliography
41
+
42
+ Click the various citations/references (e.g. `bib.anderson2010non`)
43
+ to access the [bibliography](bib).
@@ -0,0 +1,15 @@
1
+ """Root package of **DAPPER**
2
+ (Data Assimilation with Python: a Package for Experimental Research)
3
+
4
+ .. include:: ./README.md
5
+ """
6
+
7
+ __version__ = "1.5.0"
8
+
9
+ # A parsimonious list of imports used in the examples
10
+ from .dpr_config import rc
11
+ from .tools.datafiles import find_latest_run, load_xps
12
+ from .tools.rounding import round2sigfig
13
+ from .tools.seeding import set_seed
14
+ from .xp_launch import combinator, seed_and_simulate, xpList
15
+ from .xp_process import xpSpace
@@ -2,15 +2,7 @@
2
2
 
3
3
  .. include:: ./README.md
4
4
  """
5
- import dataclasses
6
- import functools
7
- import inspect
8
- import sys
9
- import time
10
- import traceback
11
- from dataclasses import dataclass
12
-
13
- import dapper.stats
5
+ from pathlib import Path
14
6
 
15
7
 
16
8
  def da_method(*default_dataclasses):
@@ -63,7 +55,7 @@ def da_method(*default_dataclasses):
63
55
  ... def assimilate(self, HMM, xx, yy):
64
56
  ... ...
65
57
 
66
- .. hint::
58
+ .. note::
67
59
  Apart from what's listed in the above `Note`, there is nothing special to the
68
60
  resulting `xp`. That is, just like any Python object, it can serve as a data
69
61
  container, and you can write any number of attributes to it (at creation-time,
@@ -71,6 +63,12 @@ def da_method(*default_dataclasses):
71
63
  `assimilate` method, but are instead used to customize other aspects of the
72
64
  experiments (see `dapper.xp_launch.run_experiment`).
73
65
  """
66
+ import dataclasses
67
+ import functools
68
+ import time
69
+ from dataclasses import dataclass
70
+
71
+ import dapper.stats
74
72
 
75
73
  def dataclass_with_defaults(cls):
76
74
  """Like `dataclass`, but add some DAPPER-specific things.
@@ -147,6 +145,9 @@ def da_method(*default_dataclasses):
147
145
 
148
146
 
149
147
  def _print_cropped_traceback(ERR):
148
+ import inspect
149
+ import sys
150
+ import traceback
150
151
 
151
152
  # A more "standard" (robust) way:
152
153
  # https://stackoverflow.com/a/32999522
@@ -181,7 +182,16 @@ def _print_cropped_traceback(ERR):
181
182
  print(msg, file=sys.stderr)
182
183
 
183
184
 
184
- from .baseline import Climatology, OptInterp, Var3D
185
+ # Import all da_methods
186
+ # for _mod in Path(__file__).parent.glob("*.py"):
187
+ # if _mod != Path(__file__) and not _mod.stem.startswith("_"):
188
+ # _mod = __import__(__package__ + "." + _mod.stem, fromlist=['*'])
189
+ # del globals()[_mod.__name__.split(".")[-1]] # rm module itself
190
+ # globals().update({k: v for k, v in vars(_mod).items()
191
+ # if isinstance(v, type) and hasattr(v, "da_method")})
192
+
193
+ # The above does not allow for go-to-definition, so
194
+ from .baseline import Climatology, OptInterp, Persistence, PreProg, Var3D
185
195
  from .ensemble import LETKF, SL_EAKF, EnKF, EnKF_N, EnKS, EnRTS
186
196
  from .extended import ExtKF, ExtRTS
187
197
  from .other import LNETF, RHF
@@ -2,7 +2,7 @@
2
2
 
3
3
  Many are based on `bib.raanes2016thesis`.
4
4
  """
5
- from typing import Optional
5
+ from typing import Callable, Optional
6
6
 
7
7
  import numpy as np
8
8
 
@@ -138,17 +138,17 @@ def fit_sigmoid(Sb, L, kb):
138
138
  """Return a sigmoid [function S(k)] for approximating error dynamics.
139
139
 
140
140
  We use the logistic function for the sigmoid; it's the solution of the
141
- "population growth" ODE: dS/dt = a*S*(1-S/S(∞)).
141
+ "population growth" ODE: `dS/dt = a*S*(1-S/S(∞))`.
142
142
  NB: It might be better to use the "error growth ODE" of Lorenz/Dalcher/Kalnay,
143
143
  but this has a significantly more complicated closed-form solution,
144
144
  and reduces to the above ODE when there's no model error (ODE source term).
145
145
 
146
- The "normalized" sigmoid, S1, is symmetric around 0, and S1(-∞)=0 and S1(∞)=1.
146
+ The "normalized" sigmoid, `S1`, is symmetric around 0, and `S1(-∞)=0` and `S1(∞)=1`.
147
147
 
148
- The sigmoid S(k) = S1(a*(k-kb) + b) is fitted (see docs/snippets/sigmoid.jpg) with
148
+ The sigmoid `S(k) = S1(a*(k-kb) + b)` is fitted (see docs/snippets/sigmoid.jpg) with
149
149
 
150
- - a corresponding to a given corr. length L.
151
- - b to match values of S(kb) and Sb
150
+ - `a` corresponding to a given corr. length `L`.
151
+ - `b` to match values of `S(kb)` and `Sb`
152
152
  """
153
153
 
154
154
  def sigmoid(k): return 1/(1+np.exp(-k)) # normalized sigmoid
@@ -164,10 +164,38 @@ def fit_sigmoid(Sb, L, kb):
164
164
 
165
165
 
166
166
  @da_method()
167
- class EnCheat:
168
- """A baseline/reference method.
167
+ class Persistence:
168
+ """Sets estimate to the **true state** at the previous time index.
169
+
170
+ The analysis (`.a`) stat uses the previous obs. time.
171
+ The forecast and universal (`.f` and `.u`) stats use previous integration time
172
+ index.
173
+ """
174
+
175
+ def assimilate(self, HMM, xx, yy):
176
+ prev = xx[0]
177
+ self.stats.assess(0, mu=prev)
178
+ for k, ko, _t, _dt in progbar(HMM.tseq.ticker):
179
+ self.stats.assess(k, ko, 'fu', mu=xx[k-1])
180
+ if ko is not None:
181
+ self.stats.assess(k, ko, 'a', mu=prev)
182
+ prev = xx[k]
169
183
 
170
- Should be implemented as part of Stats instead.
184
+
185
+ @da_method()
186
+ class PreProg:
187
+ """Simply look-up the estimates in user-specified function (`schedule`).
188
+
189
+ For example, with `schedule` given by `lambda k, xx, yy: xx[k]`
190
+ the error (`err.rms, err.ma, ...`) should be 0.
171
191
  """
172
192
 
173
- def assimilate(self, HMM, xx, yy): pass
193
+ schedule: Callable
194
+ tag: str = None
195
+
196
+ def assimilate(self, HMM, xx, yy):
197
+ self.stats.assess(0, mu=self.schedule(0, xx, yy))
198
+ for k, ko, _t, _dt in progbar(HMM.tseq.ticker):
199
+ self.stats.assess(k, ko, 'fu', mu=self.schedule(k, xx, yy))
200
+ if ko is not None:
201
+ self.stats.assess(k, ko, 'a', mu=self.schedule(k, xx, yy))