Skip to content

Commit 18da8bd

Browse files
committed
Time processing function return Tseries instances
Similar to what was done with Rprof and Field. Tseries and Vart are now in datatypes.
1 parent d7ad484 commit 18da8bd

File tree

9 files changed

+73
-69
lines changed

9 files changed

+73
-69
lines changed

docs/sources/apiref/datatypes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ datatypes
77
.. autoclass:: Field
88
.. autoclass:: Varr
99
.. autoclass:: Rprof
10+
.. autoclass:: Vart
11+
.. autoclass:: Tseries

docs/sources/apiref/phyvars.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ phyvars
3939
Dictionary of radial profiles of the reference state. Keys are the
4040
variable names, values are :class:`Varr` instances.
4141

42-
.. autoclass:: Vart
43-
4442
.. data:: TIME
4543
:annotation: = {timevar: Vart()}
4644

stagpy/commands.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ def info_cmd():
5050
series = series.copy()
5151
dimensions = []
5252
for var, val in series.iteritems():
53-
dim = phyvars.TIME.get(var) or phyvars.TIME_EXTRA.get(var)
54-
dim = dim.dim if dim is not None else '1'
53+
meta = phyvars.TIME.get(var)
54+
dim = meta.dim if meta is not None else '1'
5555
if dim == '1':
5656
dimensions.append('')
5757
else:

stagpy/datatypes.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,34 @@ class Rprof(NamedTuple):
6262
values: ndarray
6363
rad: ndarray
6464
meta: Varr
65+
66+
67+
class Vart(NamedTuple):
68+
"""Metadata of time series.
69+
70+
Attributes:
71+
description: short description of the variable if it is output by
72+
StagYY, function to compute it otherwise.
73+
kind: shorter description to group similar variables under the same
74+
label.
75+
dim: dimension used to :func:`~stagpy.stagyydata.StagyyData.scale` to
76+
dimensional values.
77+
"""
78+
79+
description: str
80+
kind: str
81+
dim: str
82+
83+
84+
class Tseries(NamedTuple):
85+
"""A time series with associated time and metadata.
86+
87+
Attributes:
88+
values: the series itself.
89+
time: the time vector.
90+
meta: the metadata of the series.
91+
"""
92+
93+
values: ndarray
94+
time: ndarray
95+
meta: Vart

stagpy/phyvars.py

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,11 @@
55
be computed from other variables.
66
"""
77

8-
from __future__ import annotations
98
from operator import attrgetter
109
from types import MappingProxyType
11-
from typing import NamedTuple, TYPE_CHECKING
1210

1311
from . import processing
14-
from .datatypes import Varf, Varr
15-
16-
if TYPE_CHECKING:
17-
from typing import Union, Callable, Tuple
18-
from numpy import ndarray
19-
from .stagyydata import StagyyData
12+
from .datatypes import Varf, Varr, Vart
2013

2114

2215
FIELD = MappingProxyType({
@@ -220,23 +213,6 @@
220213
})
221214

222215

223-
class Vart(NamedTuple):
224-
"""Metadata of time series.
225-
226-
Attributes:
227-
description: short description of the variable if it is output by
228-
StagYY, function to compute it otherwise.
229-
kind: shorter description to group similar variables under the same
230-
label.
231-
dim: dimension used to :func:`~stagpy.stagyydata.StagyyData.scale` to
232-
dimensional values.
233-
"""
234-
235-
description: Union[str, Callable[[StagyyData], Tuple[ndarray, ndarray]]]
236-
kind: str
237-
dim: str
238-
239-
240216
TIME = MappingProxyType({
241217
't': Vart('Time', 'Time', 's'),
242218
'ftop': Vart('Heat flux at top', 'Heat flux', 'W/m2'),
@@ -270,10 +246,10 @@ class Vart(NamedTuple):
270246
})
271247

272248
TIME_EXTRA = MappingProxyType({
273-
'dt': Vart(processing.dtime, 'dt', 's'),
274-
'dTdt': Vart(processing.dt_dt, r'dT/dt', 'K/s'),
275-
'ebalance': Vart(processing.ebalance, r'$\mathrm{Nu}$', '1'),
276-
'mobility': Vart(processing.mobility, 'Mobility', '1'),
249+
'dt': processing.dtime,
250+
'dTdt': processing.dt_dt,
251+
'ebalance': processing.ebalance,
252+
'mobility': processing.mobility,
277253
})
278254

279255
REFSTATE = MappingProxyType({

stagpy/processing.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,16 @@
1212
from scipy import integrate
1313

1414
from .error import NotAvailableError
15-
from .datatypes import Field, Varf, Rprof, Varr
15+
from .datatypes import Field, Varf, Rprof, Varr, Tseries, Vart
1616

1717
if typing.TYPE_CHECKING:
18-
from typing import Tuple
1918
from numpy import ndarray
2019
from .stagyydata import StagyyData
2120
from ._step import Step
2221

2322

24-
def dtime(sdat: StagyyData) -> Tuple[ndarray, ndarray]:
25-
"""Time increment dt.
23+
def dtime(sdat: StagyyData) -> Tseries:
24+
"""Compute time increment.
2625
2726
Compute dt as a function of time.
2827
@@ -32,11 +31,12 @@ def dtime(sdat: StagyyData) -> Tuple[ndarray, ndarray]:
3231
dt and time arrays.
3332
"""
3433
time = sdat.tseries.time
35-
return time[1:] - time[:-1], time[:-1]
34+
return Tseries(time[1:] - time[:-1], time[:-1],
35+
Vart("Time increment dt", 'dt', 's'))
3636

3737

38-
def dt_dt(sdat: StagyyData) -> Tuple[ndarray, ndarray]:
39-
"""Derivative of temperature.
38+
def dt_dt(sdat: StagyyData) -> Tseries:
39+
"""Compute derivative of temperature.
4040
4141
Compute dT/dt as a function of time using an explicit Euler scheme.
4242
@@ -47,11 +47,12 @@ def dt_dt(sdat: StagyyData) -> Tuple[ndarray, ndarray]:
4747
"""
4848
temp, time, _ = sdat.tseries['Tmean']
4949
dtdt = (temp[1:] - temp[:-1]) / (time[1:] - time[:-1])
50-
return dtdt, time[:-1]
50+
return Tseries(dtdt, time[:-1],
51+
Vart("Derivative of temperature", r'dT/dt', 'K/s'))
5152

5253

53-
def ebalance(sdat: StagyyData) -> Tuple[ndarray, ndarray]:
54-
"""Energy balance.
54+
def ebalance(sdat: StagyyData) -> Tseries:
55+
"""Compute energy balance.
5556
5657
Compute Nu_t - Nu_b + V*dT/dt as a function of time using an explicit
5758
Euler scheme. This should be zero if energy is conserved.
@@ -68,16 +69,17 @@ def ebalance(sdat: StagyyData) -> Tuple[ndarray, ndarray]:
6869
else:
6970
coefsurf = 1.
7071
volume = 1.
71-
dtdt, time = dt_dt(sdat)
72+
dtdt, time, _ = dt_dt(sdat)
7273
ftop = sdat.tseries['ftop'].values * coefsurf
7374
fbot = sdat.tseries['fbot'].values
7475
radio = sdat.tseries['H_int'].values
7576
ebal = ftop[1:] - fbot[1:] + volume * (dtdt - radio[1:])
76-
return ebal, time
77+
return Tseries(ebal, time,
78+
Vart("Energy balance", r'$\mathrm{Nu}$', '1'))
7779

7880

79-
def mobility(sdat: StagyyData) -> Tuple[ndarray, ndarray]:
80-
"""Plates mobility.
81+
def mobility(sdat: StagyyData) -> Tseries:
82+
"""Compute plates mobility.
8183
8284
Compute the ratio vsurf / vrms.
8385
@@ -91,7 +93,8 @@ def mobility(sdat: StagyyData) -> Tuple[ndarray, ndarray]:
9193
for step in sdat.steps.filter(rprofs=True):
9294
time.append(step.timeinfo['t'])
9395
mob.append(step.rprofs['vrms'].values[-1] / step.timeinfo['vrms'])
94-
return np.array(mob), np.array(time)
96+
return Tseries(np.array(mob), np.array(time),
97+
Vart("Plates mobility", 'Mobility', '1'))
9598

9699

97100
def delta_r(step: Step) -> Rprof:

stagpy/stagyydata.py

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@
99

1010
import re
1111
import pathlib
12-
from collections import namedtuple
1312
from itertools import zip_longest
1413

1514
import numpy as np
1615

1716
from . import conf, error, parfile, phyvars, stagyyparsers, _helpers, _step
1817
from ._helpers import CachedReadOnlyProperty as crop
19-
from .datatypes import Rprof
18+
from .datatypes import Rprof, Tseries, Vart
2019

2120

2221
def _as_view_item(obj):
@@ -159,20 +158,15 @@ def adiabats(self):
159158
return self._data[1]
160159

161160

162-
Tseries = namedtuple('Tseries', ['values', 'time', 'meta'])
163-
164-
165161
class _Tseries:
166162
"""Time series.
167163
168164
The :attr:`StagyyData.tseries` attribute is an instance of this class.
169165
170166
:class:`_Tseries` implements the getitem mechanism. Keys are series names
171-
defined in :data:`stagpy.phyvars.TIME[_EXTRA]`. An item is a named tuple
172-
('values', 'time', 'meta'), respectively the series itself, the time at
173-
which it is evaluated, and meta is a :class:`stagpy.phyvars.Vart` instance
174-
with relevant metadata. Note that series are automatically scaled if
175-
conf.scaling.dimensional is True.
167+
defined in :data:`stagpy.phyvars.TIME[_EXTRA]`. Items are
168+
:class:`stagpy.datatypes.Tseries` instances. Note that series are
169+
automatically scaled if conf.scaling.dimensional is True.
176170
177171
Attributes:
178172
sdat (:class:`StagyyData`): the StagyyData instance owning the
@@ -210,15 +204,12 @@ def __getitem__(self, name):
210204
if name in phyvars.TIME:
211205
meta = phyvars.TIME[name]
212206
else:
213-
meta = phyvars.Vart(name, None, '1')
207+
meta = Vart(name, '', '1')
214208
elif name in self._cached_extra:
215209
series, time, meta = self._cached_extra[name]
216210
elif name in phyvars.TIME_EXTRA:
217-
meta = phyvars.TIME_EXTRA[name]
218-
series, time = meta.description(self.sdat)
219-
meta = phyvars.Vart(_helpers.baredoc(meta.description),
220-
meta.kind, meta.dim)
221-
self._cached_extra[name] = series, time, meta
211+
self._cached_extra[name] = phyvars.TIME_EXTRA[name](self.sdat)
212+
series, time, meta = self._cached_extra[name]
222213
else:
223214
raise error.UnknownTimeVarError(name)
224215
series, _ = self.sdat.scale(series, meta.dim)

tests/test_phyvars.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
def test_dim():
66
allvars = chain(phyvars.FIELD.values(), phyvars.RPROF.values(),
7-
phyvars.TIME.values(), phyvars.TIME_EXTRA.values())
7+
phyvars.TIME.values())
88
for var in allvars:
99
if var.dim != '1':
1010
assert var.dim in phyvars.SCALES

tests/test_processing.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
from stagpy import processing, phyvars
22

33

4+
def tseries_checks(tseries, expected_size):
5+
assert tseries.values.shape == tseries.time.shape == (expected_size,)
6+
assert tseries.meta.dim == '1' or tseries.meta.dim in phyvars.SCALES
7+
8+
49
def rprof_checks(rprof, expected_size):
510
assert rprof.values.shape == rprof.rad.shape == (expected_size,)
611
assert rprof.meta.dim == '1' or rprof.meta.dim in phyvars.SCALES
712

813

914
def test_dt_dt(sdat):
10-
dtdt, time = processing.dt_dt(sdat)
11-
assert dtdt.shape == time.shape == (sdat.tseries.time.shape[0] - 1,)
15+
tseries_checks(processing.dt_dt(sdat), sdat.tseries.time.shape[0] - 1)
1216

1317

1418
def test_ebalance(sdat):
15-
ebal, time = processing.ebalance(sdat)
16-
assert ebal.shape == time.shape == (sdat.tseries.time.shape[0] - 1,)
19+
tseries_checks(processing.ebalance(sdat), sdat.tseries.time.shape[0] - 1)
1720

1821

1922
def test_r_edges(step):

0 commit comments

Comments
 (0)