Timelines¶
Up/down histories over a window (see the
Timelines guide). The merge functions are in
repyability.timelines.
Timeline ¶
Timeline(changes, end, up=True, *, planned=None, name=None)
A unit's up/down history over a window [0, end]: whether it is
up at 0, and the times it changes state, alternately going down and
coming back up (see repyability.timelines).
Timelines merge as a diagram's structure does (a & b is up while
both are, a | b while either is; see
series,
parallel,
k_out_of_n and
RBD.system_timeline), and each
change of a merged one keeps its cause.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
changes
|
array-like of float
|
The times the unit changes state, in increasing order, in
|
required |
end
|
float
|
The window's end, positive. |
required |
up
|
bool
|
Whether the unit is up at 0. By default True. |
True
|
planned
|
array-like of bool
|
For each change, whether it is planned (maintenance taking the unit off line) rather than a failure. Only a change down can be. By default none is. |
None
|
name
|
hashable
|
The timeline's name: the cause its changes have when it is merged with others one by one. By default None. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If a change time is not finite, is outside |
Examples:
>>> from repyability import Timeline
>>> pump = Timeline([100.0, 104.0, 900.0, 930.0], end=8760.0)
>>> pump.uptime, pump.failures
(8726.0, 2)
>>> pump.down_intervals.tolist()
[[100.0, 104.0], [900.0, 930.0]]
causes
property
¶
causes
Each change's cause: the input whose change made it (for an
unmerged timeline, its own name).
first_failure
property
¶
first_failure
The time of the first failure (unplanned change down), or inf if there is none in the window.
up_intervals
property
¶
up_intervals
The spans up, as (start, stop) rows, in order (a change and
its undoing at once leave a span of length 0).
from_outages
classmethod
¶
from_outages(outages, end, *, planned=None, name=None, merge=False)
The timeline of a unit that is up but for outages: an
outage log.
Two outages that touch, one ending as the next starts, are two
changes at one time: the unit is down throughout, but restored and
failed again at that instant, so they count as two failures. Real
logs often hold one outage as several records, overlapping or
touching (two work orders on one outage): merge=True makes each
run of them one outage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
outages
|
iterable of (float, float or None)
|
Each outage's start and end, in order of start; one ends no
later than the next starts (in any order, and overlapping, with
|
required |
end
|
float
|
The window's end, positive. |
required |
planned
|
iterable of bool
|
For each outage, whether it was planned (maintenance) rather than a failure. By default none was. Outages merged into one are planned only if all of them were. |
None
|
name
|
hashable
|
The timeline's name. By default None. |
None
|
merge
|
bool
|
Whether to join outages that overlap or touch into one, after sorting them by start. By default False: they must not overlap. |
False
|
Returns:
| Type | Description |
|---|---|
Timeline
|
Up at 0 (down, if an outage starts at 0, from a change at 0). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If an outage ends before it starts, starts before the one before
it ends (without |
Examples:
>>> from repyability import Timeline
>>> log = Timeline.from_outages([(100, 104), (900, None)], end=1000)
>>> log.downtime, log.restorations
(104.0, 1)
Two work orders on one outage, and two records of another:
>>> records = [(100, 104), (102, 110), (500, 520), (520, 530)]
>>> Timeline.from_outages(records, end=1000)
Traceback (most recent call last):
...
ValueError: Outage (102.0, 110.0) is out of order: ... merge=True ...
>>> joined = Timeline.from_outages(records, end=1000, merge=True)
>>> joined.failures, joined.downtime
(2, 40.0)
from_durations
classmethod
¶
from_durations(up_times, down_times, end, *, up=True, name=None)
The timeline of a unit that is up and down for given durations
in turn: up for up_times[0], down for down_times[0], up for
up_times[1], and so on (down first if up is False), as a
simulation draws lives and repairs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
up_times
|
array-like of float
|
The durations up, in order: non-negative (inf for ever). |
required |
down_times
|
array-like of float
|
The durations down, in order. |
required |
end
|
float
|
The window's end, positive. |
required |
up
|
bool
|
Whether the unit is up at 0. By default True. |
True
|
name
|
hashable
|
The timeline's name. By default None. |
None
|
Returns:
| Type | Description |
|---|---|
Timeline
|
The unit's changes before |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a duration is negative or not a number. |
Examples:
>>> from repyability import Timeline
>>> unit = Timeline.from_durations([10, 20, 30], [1, 2], end=50)
>>> unit.changes.tolist()
[10.0, 11.0, 31.0, 33.0]
state ¶
state(t)
Whether the unit is up at t.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
float or array-like of float
|
Times in the window. At a change, the state after it. |
required |
Returns:
| Type | Description |
|---|---|
bool or ndarray
|
True where the unit is up. |
failures_by_cause ¶
failures_by_cause()
How many failures (unplanned changes down) each cause made.
Inputs that fail at one instant are taken one after another, in
the order the inputs come (see the module docstring): of two
series inputs failing together, the first takes the timeline down
and is the cause, (x & y) giving it to x and (y & x) to
y.
Returns:
| Type | Description |
|---|---|
dict
|
Cause -> count, for every cause, in order. |
restorations_by_cause ¶
restorations_by_cause()
How many changes back up each cause made.
Returns:
| Type | Description |
|---|---|
dict
|
Cause -> count, for every cause, in order. |
to_dict ¶
to_dict()
The history as plain data, ready for json.dumps.
Returns:
| Type | Description |
|---|---|
dict
|
|
Timelines ¶
Timelines(timelines, name=None)
Up/down histories of one unit over one window [0, end]: one per
simulation, say (see repyability.timelines). Each measure is worked
out for all of them at once, as an array with one value per history.
Indexing gives a history's Timeline (a slice,
a Timelines), and Timelines merge as Timeline objects do, history by
history (a & b, a | b, and the functions of
repyability.timelines).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timelines
|
sequence of Timeline or Timelines
|
The histories, all over one window: a Timelines among them gives each of its own, in order (so Timelines of the same unit join). |
required |
name
|
hashable
|
The name: the cause the unit's own changes have when it is merged. By default the histories' own name, if they share one. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If there are no histories, or they do not share a window. |
Examples:
>>> from repyability import Timeline, Timelines
>>> runs = Timelines([Timeline([2.0, 3.0], 10.0), Timeline([], 10.0)])
>>> runs.uptime.tolist(), runs.failures.tolist()
([9.0, 10.0], [1, 0])
first_failure
property
¶
first_failure
Each history's first failure (unplanned change down), or inf.
state ¶
state(t)
Whether each history is up at t.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
float or array-like of float
|
Times in the window. At a change, the state after it. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
One row per history (one value per history for a single
|
availability_curve ¶
availability_curve()
The fraction of the histories up over time: after each time at
which one changed (and at 0 and the end), as
AvailabilityResult's
timeline and availability give it.
Returns:
| Type | Description |
|---|---|
tuple of numpy.ndarray
|
The times, in order, and the fraction up from each until the next. |
point_availability ¶
point_availability(t)
The fraction of the histories up at t.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
float or array-like of float
|
Times in the window. At a change, the state after it. |
required |
Returns:
| Type | Description |
|---|---|
float or ndarray
|
The fraction up at each time. |
failures_by_cause ¶
failures_by_cause()
How many failures (unplanned changes down) each cause made in each history.
Returns:
| Type | Description |
|---|---|
dict
|
Cause -> an array with one count per history, for every cause, in order. |
restorations_by_cause ¶
restorations_by_cause()
How many changes back up each cause made in each history.
Returns:
| Type | Description |
|---|---|
dict
|
Cause -> an array with one count per history, for every cause, in order. |
to_dict ¶
to_dict()
The histories as plain data, ready for json.dumps.
Returns:
| Type | Description |
|---|---|
dict
|
|
series ¶
series(*timelines, name=None)
The timeline of a unit that is up while all of timelines are (as
a & b).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*timelines
|
Timeline or Timelines, or a mapping of them
|
The inputs, all over one window: |
()
|
name
|
hashable
|
The result's name. By default None. |
None
|
Returns:
| Type | Description |
|---|---|
Timeline or Timelines
|
A Timelines if any input is one, else a Timeline. Each change's
cause is the input change that made it (see the module docstring
of |
Examples:
>>> from repyability import Timeline
>>> from repyability.timelines import series
>>> pump = Timeline([10.0, 12.0], end=100.0)
>>> valve = Timeline([11.0, 15.0], end=100.0)
>>> series({"pump": pump, "valve": valve}).down_intervals.tolist()
[[10.0, 15.0]]
parallel ¶
parallel(*timelines, name=None)
The timeline of a unit that is up while any of timelines is (as
a | b).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*timelines
|
Timeline or Timelines, or a mapping of them
|
The inputs, as for |
()
|
name
|
hashable
|
The result's name. By default None. |
None
|
Returns:
| Type | Description |
|---|---|
Timeline or Timelines
|
A Timelines if any input is one, else a Timeline. |
Examples:
>>> from repyability import Timeline
>>> from repyability.timelines import parallel
>>> a = Timeline([10.0, 12.0], end=100.0)
>>> b = Timeline([11.0, 15.0], end=100.0)
>>> parallel(a, b).down_intervals.tolist()
[[11.0, 12.0]]
k_out_of_n ¶
k_out_of_n(k, *timelines, name=None)
The timeline of a unit that is up while at least k of
timelines are.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
k
|
int
|
How many inputs must be up, from 1 (parallel) to their number (series). |
required |
*timelines
|
Timeline or Timelines, or a mapping of them
|
The inputs, as for |
()
|
name
|
hashable
|
The result's name. By default None. |
None
|
Returns:
| Type | Description |
|---|---|
Timeline or Timelines
|
A Timelines if any input is one, else a Timeline. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> from repyability import Timeline
>>> from repyability.timelines import k_out_of_n
>>> units = [Timeline(c, end=100.0) for c in ([5, 9], [7, 12], [8, 20])]
>>> k_out_of_n(2, *units).down_intervals.tolist()
[[7.0, 12.0]]