Table Of Contents

Previous topic

Welcome to pyrem’s documentation!

Next topic

pyrem.polygram module

This Page

pyrem.time_series module

Biological time series

This module provides data structure for two types of time series: Signal and Annotation.

Both structures extend ndarray by providing attributes, such as sampling frequency, metadata, name. More importantly, time series provide specific features such as indexing with time strings.

>>> import pyrem as pr
>>> import numpy as np
>>> # generate white noise:
>>> noise = np.random.normal(size=int(1e6))
>>> # a million point sampled at 256 Hz

Then, to create a time series from this vector of random numbers:

>>> sig = pr.time_series.Signal(noise, 256.0,
>>>                             type="noise", name="channel_1",
>>>                             metadata={"patient": "John_Doe"})

Display information about this time series:

>>> sig

To resample at 100 Hz:

>>> sig_short =  sig.resample(100.0)
>>> sig_short

Time series derive from numpy arrays, so you can just use them as such:

>>> sig_norm = sig - np.mean(sig)
Note that the resulting signal is conveniently a time series (not a regular numpy array)
>>> np.diff(sig)

Indexing time series

As numpy arrays

Since time series are derived from numpy array, the numpy indexing rule apply:

>>> sig[1:1000:3] # one to 999, every 3 values
>>> sig[: -100] # from start to 0 to 100 before the end

See numpy documentation for more info.

With strings and time-deltas

It is common to have to extract a signal between two different time points. Instead of having to tediously calculate index from time, pyrem offers the possibility to use stings and datetime.timedelta

Time strings are represented with the following format:

“29h33m1.02s”

Where:

  • h is for hour
  • m for minutes
  • s for seconds

Example:

>>> # string indexing:
>>> print sig.duration
>>> sig2 = sig["1h2m2s":]  # everything after 1 hour, 2 min and 2 seconds
>>> print sig2.duration
>>> # this should be exactly 1h2m2s
>>> print sig.duration - sig2.duration
>>> print sig["1h2m2s":"1h2m2.1s"]

Note

When indexing a signal with time strings, we query the values of a discrete representation of a continuous signal. Therefore, it makes no sense to obtain a signal of length zero. For instance, imagine a signal of 10 seconds sampled at 1Hz. If we query the value between 1.5 and 1.6s, no points fall in this interval. However, the signal does have a value. In this case, pyrem returns a signal of length 1 where the unique value is the value of the former neighbour.

>>> sig = pr.time_series.Signal([3,4,2,6,4,7,4,5,7,9], 10.0,)
>>> sig["0s":"0.001s"])
>>> sig["0s":"0.011s"])

Epoch iteration

A common task is to extract successive temporal slices (i.e. epochs) of a signal, for instance, in order to compute features. iter_window() iterator facilitates this.

Let us work wit a one minute signal as an example:

>>> sig1m = sig[:"1m"]

Get every 5 seconds of a the first minutes of a signal:

>>> for time, sub_signal in sig1m.iter_window(5,1.0):
>>>     print time, sub_signal.duration

Get 10 second epochs, overlapping of 50% (5s):

>>> for time, sub_signal in sig1m.iter_window(10,0.5):
>>>     print time, sub_signal.duration

Get 1 second epochs, skipping every other epoch

>>> for time, sub_signal in sig1m.iter_window(1,2.0):
>>>     print time, sub_signal.duration
class pyrem.time_series.Annotation(data, fs, observation_probabilities=None, **kwargs)[source]

Bases: pyrem.time_series.BiologicalTimeSeries

Annotations are time series of discrete values associated with a probability/confidence of observing this value. BiologicalTimeSeries indexing rules apply to them.

Parameters:
  • data – a vector representing different states. It should be a uint8 one-d array like structure (typically, a ndarray)
  • fs (float) – the sampling frequency
  • observation_probabilities – an array of confidence/ probability of observation of the states. it should be a one-d array-like of floats of length len(data). If None, confidence are assumed to be equal to one for all observations.
  • kwargs – key word arguments to be passed to BiologicalTimeSeries
probas[source]

The probabilities/confidences associated to the annotation values.

Returns:an array of float32
Return type:ndarray
resample(target_fs)[source]

Resample annotations to a new sampling frequency. Values are resampled with nearest neighbour interpolation, while associated probabilities are linearly interpolated.

Parameters:target_fs (float) – The target sampling frequency
Returns:a new Annotation object
values[source]

The values of each annotations.

Returns:an array of uint8
Return type:ndarray
class pyrem.time_series.BiologicalTimeSeries(data, fs, type=None, name=None, metadata=None)[source]

Bases: numpy.ndarray

An abstract class for time series.

Parameters:
  • data – an one-d array like structure (typically, a ndarray)
  • fs (float) – the sampling frequency
  • type (str) – the type of time series (e.g. “eeg”, “temperature”, “blood_pH”)
  • name (str) – a unique name to identify a time series contained in a Polygram
  • metadata (dict) – a dictionary of additional information (e.g. experimental variables)
copy()[source]

Deep copy a time series.

Returns:A new time series with identical values and attributes
Return type:BiologicalTimeSeries
duration[source]
Returns:the total duration of the time series
Return type:datetime
fs[source]
Returns:the sampling frequency of the time series
Return type:float
iter_window(length, lag)[source]

Iterate through an array by successive (possibly overlapping) slices (i.e. epochs). Conveniently, the central time ot the epoch is also returned.

Parameters:
  • lag (float) – the ratio of overlap (1 = no overlap, 0 = completely overlapped, 2 = skip every other epoch)
  • length (float) – duration of the epochs (in second)
Returns:

(centre_of_window, BiologicalTimeSeries)

metadata[source]
Returns:a dictionary of metadata (i.e. information about data acquisition)
Return type:dict
name[source]

The name of the signal. It is expected to be unique.

Returns:the user-defined name for this signal
Return type:str
rename(name)[source]

Rename the signal

Parameters:name (str) – the new name
resample(new_fs)[source]

Abstract method for resampling a time series (behaves differently according to the type of time series)

Note

Because time series are digital (i.e. discrete) the resulting sampling rate is expected to be slightly different from the target sampling rate.

Parameters:new_fs (float) – the target time series
Returns:a new BiologicalTimeSeries
save(filename, compression_level=5)[source]

Efficiently save a time series using joblib

Parameters:
  • filename (str) – the output file name
  • compression_level (int) – an integer between 1 and 9. More is better, but slower. 5 is generally a good compromise
type[source]
Returns:the user-defined type of time series (e.g. “eeg” or “ecg”)
Return type:str
class pyrem.time_series.Signal(data, fs, **kwargs)[source]

Bases: pyrem.time_series.BiologicalTimeSeries

resample(target_fs, mode='sinc_best')[source]

Resample the signal. One implication of the signal being digital, is that the resulting sampling frequency is not guaranteed to be exactly at target_fs. This method wraps resample()

Parameters:
  • target_fs (float) – The new sampling frequency
  • mode (str) – to be passed to resample()
Returns: