diff --git a/dapper/da_methods/__init__.py b/dapper/da_methods/__init__.py index bf13340c..83ca5f59 100644 --- a/dapper/da_methods/__init__.py +++ b/dapper/da_methods/__init__.py @@ -16,7 +16,7 @@ def da_method(*default_dataclasses): The decorated classes are defined like a `dataclass`, but are decorated by `@da_method()` instead of `@dataclass`. - .. note:: + !!! note The classes must define a method called `assimilate`. This method gets slightly enhanced by this wrapper which provides: @@ -56,7 +56,7 @@ def da_method(*default_dataclasses): ... def assimilate(self, HMM, xx, yy): ... ... - .. note:: + !!! note Apart from what's listed in the above `Note`, there is nothing special to the resulting `xp`. That is, just like any Python object, it can serve as a data container, and you can write any number of attributes to it (at creation-time, diff --git a/dapper/da_methods/particle.py b/dapper/da_methods/particle.py index b3f1fbbd..8dd72be9 100644 --- a/dapper/da_methods/particle.py +++ b/dapper/da_methods/particle.py @@ -94,9 +94,8 @@ class OptPF: Ref: `bib.bocquet2010beyond`. - .. note:: Regularization (`Qs`) is here added BEFORE Bayes' rule. - If `Qs==0`: OptPF should be equal to - the bootstrap filter `PartFilt`. + !!! note Regularization (`Qs`) is here added BEFORE Bayes' rule. + If `Qs==0`: OptPF should be equal to the bootstrap filter `PartFilt`. """ N: int diff --git a/dapper/mods/LA/evensen2009.py b/dapper/mods/LA/evensen2009.py index 5dd4a854..ac08981f 100644 --- a/dapper/mods/LA/evensen2009.py +++ b/dapper/mods/LA/evensen2009.py @@ -1,6 +1,6 @@ """A mix of `bib.evensen2009ensemble` and `bib.sakov2008implications`. -.. note:: +!!! note Since there is no noise, and the system is stable, the rmse's from this HMM go to zero as `T` goes to infinity. Thus, benchmarks largely depend on the initial error, diff --git a/dapper/mods/README.md b/dapper/mods/README.md index 63b800ac..b6bae097 100644 --- a/dapper/mods/README.md +++ b/dapper/mods/README.md @@ -56,7 +56,7 @@ try not to import stuff from DAPPER outside of `dapper.mods` and `liveplotting`. - `dapper.mods.QG`: use of parallelized for loop (map). - .. note:: + !!! note To begin with, test whether the model works on 1 realization, before running it with several (simultaneously). Also, start with a small integration time step, @@ -64,7 +64,7 @@ try not to import stuff from DAPPER outside of `dapper.mods` and `liveplotting`. Note that the time step might need to be shorter in assimilation, because it may cause instabilities. - .. note:: + !!! note Most models are defined using simple procedural style. However, `dapper.mods.LorenzUV` and `dapper.mods.QG` use OOP, which is perhaps more robust when different diff --git a/dapper/mods/__init__.py b/dapper/mods/__init__.py index 4f91f766..ed708268 100644 --- a/dapper/mods/__init__.py +++ b/dapper/mods/__init__.py @@ -32,23 +32,23 @@ class HiddenMarkovModel(struct_tools.NicePrint): The synthetic truth and observations may then be obtained by running `HiddenMarkovModel.simulate`. - .. note:: - Each model included with DAPPER comes with several examples - of model settings from the literature. - See, for example, `dapper.mods.Lorenz63.sakov2012`. - - .. warning:: - These example configurations do not necessarily hold a high programming standard, - as they may have been whipped up at short notice to replicate some experiments, - and are not intended for re-use. - Nevertheless, sometimes they are re-used by another configuration script, - leading to a major gotcha/pitfall: changes made to the imported `HMM` (or - the model's module itself) also impact the original object (since they - are mutable and thereby referenced). This *usually* isn't an issue, since - one rarely imports two/more separate configurations. However, the test suite - imports all configurations, which might then unintentionally interact. - To avoid this, you should use the `copy` method of the `HMM` - before making any changes to it. + !!! note + Each model included with DAPPER comes with several examples + of model settings from the literature. + See, for example, `dapper.mods.Lorenz63.sakov2012`. + + !!! warning + These example configs do not necessarily hold a high programming standard, + as they may have been whipped up at short notice to replicate some experiments, + and are not intended for re-use. + Nevertheless, sometimes they are re-used by another configuration script, + leading to a major gotcha/pitfall: changes made to the imported `HMM` (or + the model's module itself) also impact the original object (since they + are mutable and thereby referenced). This *usually* isn't an issue, since + one rarely imports two/more separate configurations. However, the test suite + imports all configurations, which might then unintentionally interact. + To avoid this, you should use the `copy` method of the `HMM` + before making any changes to it. Parameters diff --git a/dapper/mods/integration.py b/dapper/mods/integration.py index 46d4da87..8c82c2ec 100644 --- a/dapper/mods/integration.py +++ b/dapper/mods/integration.py @@ -98,7 +98,7 @@ def with_recursion(func, prog=False): Return a version of `func` whose 2nd argument (`k`) specifies the number of times to times apply func on its output. - .. warning:: Only the first argument to `func` will change, + !!! warning Only the first argument to `func` will change, so, for example, if `func` is `step(x, t, dt)`, it will get fed the same `t` and `dt` at each iteration. @@ -154,10 +154,13 @@ def integrate_TLM(TLM, dt, method='approx'): - the Jacobian of the step func. - the integral of (with *M* as the TLM): - $$ \frac{d U}{d t} = M U, \quad U_0 = I .$$ - .. note:: the tangent linear model (TLM) - is assumed constant (for each `method` below). + $$ + \frac{d U}{d t} = M U, \quad U_0 = I . + $$ + + !!! tip "The tangent linear model (TLM)" + is assumed constant (for each `method` below). Parameters ---------- @@ -166,7 +169,9 @@ def integrate_TLM(TLM, dt, method='approx'): - `'approx'` : derived from the forward-euler scheme. - `'rk4'` : higher-precision approx. - `'analytic'`: exact. - .. warning:: 'analytic' typically requries higher inflation in the ExtKF. + + !!! warning + "'analytic' typically requries higher inflation in the ExtKF." See Also -------- diff --git a/dapper/mods/utils.py b/dapper/mods/utils.py index f5beb1d5..799387bd 100644 --- a/dapper/mods/utils.py +++ b/dapper/mods/utils.py @@ -42,8 +42,8 @@ def ens_compatible(func): This is helpful to make functions compatible with both 1d and 2d ndarrays. - .. note:: This is not `the_way™` -- other tricks (ref `dapper.mods`) - are sometimes more practical. + !!! tip "This is not `the_way™`" + Other tricks (ref `dapper.mods`) are sometimes more practical. Examples -------- @@ -70,15 +70,16 @@ def linear_model_setup(ModelMatrix, dt0): r"""Make the Dyn/Obs field of a HMM representing a linear model. Let *M* be the model matrix. Then - .. math:: - x(t+dt) = M^{dt/dt0} x(t), + $$ + x(t+dt) = M^{dt/dt0} x(t), + $$ i.e. - .. math:: - - \frac{dx}{dt} = \frac{\log(M)}{dt0} x(t). + $$ + \frac{dx}{dt} = \frac{\log(M)}{dt0} x(t). + $$ In typical use, `dt0==dt` (where `dt` is defined by the chronology). Anyways, `dt` must be an integer multiple of `dt0`. diff --git a/dapper/stats.py b/dapper/stats.py index 29d05850..8d173467 100644 --- a/dapper/stats.py +++ b/dapper/stats.py @@ -439,11 +439,12 @@ def replay(self, figlist="default", speed=np.inf, t1=0, t2=None, **kwargs): - t1, t2: time window to plot. - 'figlist' and 'speed': See LivePlot's doc. - .. note:: `store_u` (whether to store non-obs-time stats) must - have been `True` to have smooth graphs as in the actual LivePlot. + !!! note + `store_u` (whether to store non-obs-time stats) must + have been `True` to have smooth graphs as in the actual LivePlot. - .. note:: Ensembles are generally not stored in the stats - and so cannot be replayed. + !!! note + Ensembles are generally not stored in the stats and so cannot be replayed. """ # Time settings tseq = self.HMM.tseq diff --git a/dapper/stats_etc.md b/dapper/stats_etc.md index 1bdd5ee2..b14fccdd 100644 --- a/dapper/stats_etc.md +++ b/dapper/stats_etc.md @@ -28,7 +28,8 @@ This is done according to the methods listed in `dpr.rc.field_summaries`. nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa. -.. note:: +!!! note + Although sometimes pretty close, `rmv` (a.k.a. `spread.rms`) is not (supposed to be) an un-biased estimator of `rmse` (a.k.a. `err.rms`). This is because of the square roots involved in the field summary. Instead, `spread.ms` (i.e. diff --git a/dapper/tools/chronos.py b/dapper/tools/chronos.py index fd169805..e61f3e28 100644 --- a/dapper/tools/chronos.py +++ b/dapper/tools/chronos.py @@ -24,9 +24,9 @@ class Chronology: kko: 2 4 6 [----dko------] - .. warning:: By convention, there is no obs at 0. - This is hardcorded in DAPPER, - whose cycling starts by the forecast. + !!! warning + By convention, there is no obs at 0. + This is hardcorded in DAPPER, whose cycling starts by the forecast. Identities (subject to precision): diff --git a/dapper/tools/multiproc.py b/dapper/tools/multiproc.py index 98caaf31..a27d69d6 100644 --- a/dapper/tools/multiproc.py +++ b/dapper/tools/multiproc.py @@ -48,13 +48,13 @@ def Pool(NPROC=None): so you likely want to re-use a pool rather than repeatedly creating one. Consider using `functools.partial` to fix kwargs. - .. note:: + !!! note In contrast to *reading*, in-place writing does not work with multiprocessing. This changes with "shared" arrays, but that has not been tested here. By contrast, multi*threading* shares the process memory, but was significantly slower in the tested (pertinent) cases. - .. warning:: + !!! warning `multiprocessing` does not mix with `matplotlib`, so ensure `func` does not reference `xp.stats.LP_instance`. In fact, `func` should not reference `xp` at all, because it takes time to serialize. diff --git a/dapper/tools/series.py b/dapper/tools/series.py index 82a186bb..6b8f932c 100644 --- a/dapper/tools/series.py +++ b/dapper/tools/series.py @@ -210,8 +210,9 @@ class FAUSt(DataSeries, StatPrint): self[k,'u'] self[k,whatever,'u'] - .. note:: If a data series only pertains to analysis times, - then you should use a plain np.array instead. + !!! note + If a data series only pertains to analysis times, then you should use a plain + np.array instead. """ def __init__(self, K, Ko, item_shape, store_u, store_s, **kwargs): diff --git a/dapper/tools/viz.py b/dapper/tools/viz.py index c14918c2..b2645ba6 100644 --- a/dapper/tools/viz.py +++ b/dapper/tools/viz.py @@ -403,14 +403,14 @@ def plot_err_components(stats): ---------- stats: `dapper.stats.Stats` - .. note:: - it was chosen to `plot(ii, mean_in_time(abs(err_i)))`, - and thus the corresponding spread measure is MAD. - If one chose instead: `plot(ii, std_spread_in_time(err_i))`, - then the corresponding measure of spread would have been `spread`. - This choice was made in part because (wrt. subplot 2) - the singular values (`svals`) correspond to rotated MADs, - and because `rms(umisf)` seems too convoluted for interpretation. + !!! note + It was chosen to `plot(ii, mean_in_time(abs(err_i)))`, + and thus the corresponding spread measure is MAD. + If one chose instead: `plot(ii, std_spread_in_time(err_i))`, + then the corresponding measure of spread would have been `spread`. + This choice was made in part because (wrt. subplot 2) + the singular values (`svals`) correspond to rotated MADs, + and because `rms(umisf)` seems too convoluted for interpretation. """ fig, (ax0, ax1, ax2) = place.freshfig("Error components", figsize=(6, 6), nrows=3) diff --git a/dapper/xp_launch.py b/dapper/xp_launch.py index 58cc5701..107547c9 100644 --- a/dapper/xp_launch.py +++ b/dapper/xp_launch.py @@ -43,7 +43,7 @@ def seed_and_simulate(HMM, xp): xp: object Type: a `dapper.da_methods.da_method`-decorated class. - .. warning:: `xp.seed` should be set (and `int`). + !!! warning "`xp.seed` should be set (and `int`)." Without `xp.seed` the seed does not get set, and different `xp`s will use different seeds @@ -634,7 +634,7 @@ def combinator(param_dict, **glob_dict): - specified as keywords to the `for_params` fix the value preventing using the corresponding (if any) value list in the `param_dict`. - .. warning:: + !!! warning Beware! If, eg., `infl` or `rot` are in `param_dict`, aimed at the `EnKF`, but you forget that they are also attributes some method where you don't actually want to use them (eg. `SVGDF`), diff --git a/dapper/xp_process.py b/dapper/xp_process.py index 32c9f230..2efbb5dc 100644 --- a/dapper/xp_process.py +++ b/dapper/xp_process.py @@ -479,8 +479,8 @@ def table_tree(self, statkey, dims, *, costfun=None): by the mean/tune operations. The `dims['outer']` and `dims['inner'] become the keys for the output hierarchy. - .. note:: - cannot support multiple `statkey`s because it's not (obviously) meaningful + !!! note + Cannot support multiple `statkey`s because it's not (obviously) meaningful when optimizing over `dims['optim']`. """ diff --git a/docs/dev_guide.md b/docs/dev_guide.md index c1118b38..53e0c4fa 100644 --- a/docs/dev_guide.md +++ b/docs/dev_guide.md @@ -85,7 +85,7 @@ For detailed linting messages, run ruff check --output-format=concise ``` -.. warning:: Obsolete +!!! warning "Obsolete" Kept for reference. You may also want to display linting issues in your editor as you code.