Skip to content

Commit 1a931a1

Browse files
committed
New time series interface
This commit is similar to what was done for radial profiles in commit d794fa1. In particular: - items of sdat.tseries are named tuples with values, time, and meta fields; - EXTRA variables are accessible through the same interface as regular variables; - processing functions no longer have tstart/tend as arguments; - time_series.get_time_series is removed, replaced by tseries[]; - tseries.tslice replaces sdat.tseries_between; - tseries.time offers easy access to the time coordinate. Moreover compstat is now a list of time variable for which statistics are desired.
1 parent 28b7f50 commit 1a931a1

File tree

10 files changed

+209
-241
lines changed

10 files changed

+209
-241
lines changed

docs/sources/stagyydata.rst

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ Radial profiles
8989
Radial profile data are accessible trough the :attr:`~stagpy._step.Step.rprofs`
9090
attribute of a :class:`~stagpy._step.Step` instance. This attribute implements
9191
getitem to access radial profiles. Keys are the names of available
92-
variables (such as e.g. ``'Tmean'`` and ``'ftop'``). Items are named tuples
92+
variables (such as e.g. ``'Tmean'`` and ``'vzabs'``). Items are named tuples
9393
with three fields:
9494

9595
- :data:`values`: the profile itself;
@@ -108,29 +108,27 @@ the 1000th timestep.
108108
Time series
109109
-----------
110110

111-
Temporal data are contained in the
111+
Temporal data are accessible through the
112112
:attr:`~stagpy.stagyydata.StagyyData.tseries` attribute of a
113-
:class:`~stagpy.stagyydata.StagyyData` instance. This attribute is a
114-
:class:`pandas.DataFrame`. Its :attr:`columns` are the names of available
115-
variables. Its :attr:`index` is the time steps number (:attr:`istep`). The list
116-
of available variables can be obtained by running ``% stagpy var``.
117-
118-
The temporal data of a given time step can be accessed from
119-
:attr:`_Step.timeinfo <stagpy.stagyydata._Step.timeinfo>`. For example,
120-
``sdat.steps[1000].timeinfo`` is equivalent to ``sdat.tseries.loc[1000]``. Both
121-
are :class:`pandas.Series` indexed by the available variables.
122-
123-
As an example, the following lines are three ways of accessing the average
124-
temperature at the 1000th timestep::
125-
126-
# extract time series info available for the 1000th timestep,
127-
# and then take the average temperature
128-
sdat.steps[1000].timeinfo['Tmean']
129-
# extract the temperature time series,
130-
# and then take the 1000th timestep
131-
sdat.tseries['Tmean'][1000]
132-
# direct access to the wanted info
133-
sdat.tseries.loc[1000, 'Tmean']
113+
:class:`~stagpy.stagyydata.StagyyData` instance. This attribute implements
114+
getitem to access time series. Keys are the names of available variables
115+
(such as e.g. ``'Tmean'`` and ``'ftop'``). Items are named tuples with
116+
three fields:
117+
118+
- :data:`values`: the series itself;
119+
- :data:`time`: the times at which the series is evaluated;
120+
- :data:`meta`: metadata of the series, also a named tuple with:
121+
122+
- :data:`description`: explanation of what the series is;
123+
- :data:`kind`: the category of series;
124+
- :data:`dim`: the dimension of the series (if applicable) in SI units.
125+
126+
The list of available variables can be obtained by running ``% stagpy var``.
127+
128+
The time series data at a given time step can be accessed from
129+
:attr:`Step.timeinfo <stagpy._step.Step.timeinfo>`. For example,
130+
``sdat.steps[1000].timeinfo`` is equivalent to ``sdat.tseries.at_step(1000)``.
131+
Both are :class:`pandas.Series` indexed by the available variables.
134132

135133

136134
Geometry

stagpy/_step.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -529,13 +529,8 @@ def geom(self):
529529

530530
@property
531531
def timeinfo(self):
532-
"""Time series data of the time step.
533-
534-
Set to None if no time series data is available for this time step.
535-
"""
536-
if self.istep not in self.sdat.tseries.index:
537-
return None
538-
return self.sdat.tseries.loc[self.istep]
532+
"""Time series data of the time step."""
533+
return self.sdat.tseries.at_step(self.istep)
539534

540535
@property
541536
def isnap(self):

stagpy/config.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@ def _index_collection(arg):
144144
('style',
145145
Conf('-', True, None, {},
146146
True, 'matplotlib line style')),
147-
('compstat', switch_opt(False, None, 'compute steady state statistics')),
147+
('compstat',
148+
Conf('', True, None, {'nargs': '?', 'const': ''},
149+
False, 'compute mean and rms of listed variables')),
148150
('tstart',
149151
Conf(None, True, None, {'type': float},
150152
False, 'beginning time')),

stagpy/misc.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,22 @@ def set_of_vars(lovs):
121121
return set(var for pvars in lovs for svars in pvars for var in svars)
122122

123123

124+
def find_in_sorted_arr(value, array, after=False):
125+
"""Return position of element in a sorted array.
126+
127+
Returns:
128+
int: the maximum position i such as array[i] <= value. If after is
129+
True, it returns the min i such as value <= array[i] (or 0 if such
130+
an indices does not exist).
131+
"""
132+
ielt = array.searchsorted(value)
133+
if ielt == array.size:
134+
ielt -= 1
135+
if not after and array[ielt] != value and ielt > 0:
136+
ielt -= 1
137+
return ielt
138+
139+
124140
class InchoateFiles:
125141
"""Context manager handling files whose names are not known yet.
126142

stagpy/processing.py

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,97 +11,75 @@
1111
from .error import NotAvailableError
1212

1313

14-
def dtime(sdat, tstart=None, tend=None):
14+
def dtime(sdat):
1515
"""Time increment dt.
1616
1717
Compute dt as a function of time.
1818
1919
Args:
2020
sdat (:class:`~stagpy.stagyydata.StagyyData`): a StagyyData instance.
21-
tstart (float): time at which the computation should start. Use the
22-
beginning of the time series data if set to None.
23-
tend (float): time at which the computation should end. Use the
24-
end of the time series data if set to None.
2521
Returns:
2622
tuple of :class:`numpy.array`: dt and time arrays.
2723
"""
28-
tseries = sdat.tseries_between(tstart, tend)
29-
time = tseries['t'].values
24+
time = sdat.tseries.time
3025
return time[1:] - time[:-1], time[:-1]
3126

3227

33-
def dt_dt(sdat, tstart=None, tend=None):
28+
def dt_dt(sdat):
3429
"""Derivative of temperature.
3530
3631
Compute dT/dt as a function of time using an explicit Euler scheme.
3732
3833
Args:
3934
sdat (:class:`~stagpy.stagyydata.StagyyData`): a StagyyData instance.
40-
tstart (float): time at which the computation should start. Use the
41-
beginning of the time series data if set to None.
42-
tend (float): time at which the computation should end. Use the
43-
end of the time series data if set to None.
4435
Returns:
4536
tuple of :class:`numpy.array`: derivative of temperature and time
4637
arrays.
4738
"""
48-
tseries = sdat.tseries_between(tstart, tend)
49-
time = tseries['t'].values
50-
temp = tseries['Tmean'].values
39+
temp, time, _ = sdat.tseries['Tmean']
5140
dtdt = (temp[1:] - temp[:-1]) / (time[1:] - time[:-1])
5241
return dtdt, time[:-1]
5342

5443

55-
def ebalance(sdat, tstart=None, tend=None):
44+
def ebalance(sdat):
5645
"""Energy balance.
5746
5847
Compute Nu_t - Nu_b + V*dT/dt as a function of time using an explicit
5948
Euler scheme. This should be zero if energy is conserved.
6049
6150
Args:
6251
sdat (:class:`~stagpy.stagyydata.StagyyData`): a StagyyData instance.
63-
tstart (float): time at which the computation should start. Use the
64-
beginning of the time series data if set to None.
65-
tend (float): time at which the computation should end. Use the
66-
end of the time series data if set to None.
6752
Returns:
6853
tuple of :class:`numpy.array`: energy balance and time arrays.
6954
"""
70-
tseries = sdat.tseries_between(tstart, tend)
7155
rbot, rtop = sdat.steps[-1].rprofs.bounds
7256
if rbot != 0: # spherical
7357
coefsurf = (rtop / rbot)**2
7458
volume = rbot * ((rtop / rbot)**3 - 1) / 3
7559
else:
7660
coefsurf = 1.
7761
volume = 1.
78-
dtdt, time = dt_dt(sdat, tstart, tend)
79-
ftop = tseries['ftop'].values * coefsurf
80-
fbot = tseries['fbot'].values
81-
radio = tseries['H_int'].values
62+
dtdt, time = dt_dt(sdat)
63+
ftop = sdat.tseries['ftop'].values * coefsurf
64+
fbot = sdat.tseries['fbot'].values
65+
radio = sdat.tseries['H_int'].values
8266
ebal = ftop[1:] - fbot[1:] + volume * (dtdt - radio[1:])
8367
return ebal, time
8468

8569

86-
def mobility(sdat, tstart=None, tend=None):
70+
def mobility(sdat):
8771
"""Plates mobility.
8872
8973
Compute the ratio vsurf / vrms.
9074
9175
Args:
9276
sdat (:class:`~stagpy.stagyydata.StagyyData`): a StagyyData instance.
93-
tstart (float): time at which the computation should start. Use the
94-
beginning of the time series data if set to None.
95-
tend (float): time at which the computation should end. Use the
96-
end of the time series data if set to None.
9777
Returns:
9878
tuple of :class:`numpy.array`: mobility and time arrays.
9979
"""
100-
tseries = sdat.tseries_between(tstart, tend)
101-
steps = sdat.steps[tseries.index[0]:tseries.index[-1]]
10280
time = []
10381
mob = []
104-
for step in steps.filter(rprofs=True):
82+
for step in sdat.steps.filter(rprofs=True):
10583
time.append(step.timeinfo['t'])
10684
mob.append(step.rprofs['vrms'].values[-1] / step.timeinfo['vrms'])
10785
return np.array(mob), np.array(time)

0 commit comments

Comments
 (0)