Skip to content

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 [0, end] (one at end changes nothing in the window and is dropped). Two at one time are a change and its undoing at once (an instant repair).

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 [0, end] or out of order, if end is not positive and finite, or if planned does not have one flag per change or flags a change back up.

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]]

end property

end

The window's end.

up property

up

Whether the unit is up at 0.

name property

name

The timeline's name (see Timeline).

changes property

changes

The times the unit changes state, in order.

causes property

causes

Each change's cause: the input whose change made it (for an unmerged timeline, its own name).

planned property

planned

For each change, whether it is a planned change down.

uptime property

uptime

The time up in the window.

downtime property

downtime

The time down in the window.

availability property

availability

The fraction of the window up.

failures property

failures

The unplanned changes down.

planned_outages property

planned_outages

The planned changes down.

restorations property

restorations

The changes back up.

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).

down_intervals property

down_intervals

The spans down, as (start, stop) rows, in order.

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 merge). An end of None, or at or after the window's end, runs to the end.

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 merge), or starts outside [0, end], or planned does not have one flag per outage.

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 end. Once the durations run out it stays as it is.

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

end, up (at 0), name, changes (the times it changes state), causes (each change's cause) and planned (whether each is a planned change down).

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])

end property

end

The window's end.

name property

name

The name (see Timelines).

up property

up

Whether each history starts up.

uptime property

uptime

Each history's time up.

downtime property

downtime

Each history's time down.

availability property

availability

Each history's fraction of the window up.

failures property

failures

Each history's failures (unplanned changes down).

planned_outages property

planned_outages

Each history's planned changes down.

restorations property

restorations

Each history's changes back up.

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 t): True where it is up.

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

end, name and timelines, each history's Timeline.to_dict(), in order.

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: Timeline objects, or Timelines with as many histories each (a Timeline among them stands for each history). Given as one mapping, {label: timeline}, each input is a cause of its own, labelled by its key; given one by one, each input's changes keep their causes (an unmerged timeline's, its name).

()
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 repyability.timelines).

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 series.

()
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 series.

()
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 k is not a whole number from 1 to the number of inputs.

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]]