processing

The processing subpackage contains signal-processing tools.

Basic Utility

Basic signal processing functions

wfdb.processing.get_filter_gain(b, a, f_gain, fs)

Given filter coefficients, return the gain at a particular frequency.

Parameters
blist

List of linear filter b coefficients.

alist

List of linear filter a coefficients.

f_gainint, float, optional

The frequency at which to calculate the gain.

fsint, float, optional

The sampling frequency of the system.

Returns
gainint, float

The passband gain at the desired frequency.

wfdb.processing.normalize_bound(sig, lb=0, ub=1)

Normalize a signal between the lower and upper bound.

Parameters
signdarray

Original signal to be normalized.

lbint, float, optional

Lower bound.

ubint, float, optional

Upper bound.

Returns
ndarray

Normalized signal.

wfdb.processing.resample_ann(ann_sample, fs, fs_target)

Compute the new annotation indices.

Parameters
ann_samplendarray

Array of annotation locations.

fsint

The starting sampling frequency.

fs_targetint

The desired sampling frequency.

Returns
ndarray

Array of resampled annotation locations.

wfdb.processing.resample_multichan(xs, ann, fs, fs_target, resamp_ann_chan=0)

Resample multiple channels with their annotations.

Parameters
xs: ndarray

The signal array.

annWFDB Annotation

The WFDB annotation object.

fsint, float

The original frequency.

fs_targetint, float

The target frequency.

resample_ann_channelint, optional

The signal channel used to compute new annotation indices.

Returns
ndarray

Array of the resampled signal values.

resampled_annWFDB Annotation

Annotation containing resampled annotation locations.

wfdb.processing.resample_sig(x, fs, fs_target)

Resample a signal to a different frequency.

Parameters
xndarray

Array containing the signal.

fsint, float

The original sampling frequency.

fs_targetint, float

The target frequency.

Returns
resampled_xndarray

Array of the resampled signal values.

resampled_tndarray

Array of the resampled signal locations.

wfdb.processing.resample_singlechan(x, ann, fs, fs_target)

Resample a single-channel signal with its annotations.

Parameters
x: ndarray

The signal array.

annWFDB Annotation

The WFDB annotation object.

fsint, float

The original frequency.

fs_targetint, float

The target frequency.

Returns
resampled_xndarray

Array of the resampled signal values.

resampled_annWFDB Annotation

Annotation containing resampled annotation locations.

Heart Rate

wfdb.processing.ann2rr(record_name, extension, pn_dir=None, start_time=None, stop_time=None, format=None, as_array=True)

Obtain RR interval series from ECG annotation files.

Parameters
record_namestr

The record name of the WFDB annotation file. ie. for file ‘100.atr’, record_name=’100’.

extensionstr

The annotatator extension of the annotation file. ie. for file ‘100.atr’, extension=’atr’.

pn_dirstr, optional

Option used to stream data from Physionet. The PhysioNet database directory from which to find the required annotation file. eg. For record ‘100’ in ‘http://physionet.org/content/mitdb’: pn_dir=’mitdb’.

start_timefloat, optional

The time to start the intervals in seconds.

stop_timefloat, optional

The time to stop the intervals in seconds.

formatstr, optional

Print intervals in the specified format. By default, intervals are printed in units of sample intervals. Other formats include ‘s’ (seconds), ‘m’ (minutes), ‘h’ (hours). Set to ‘None’ for samples.

as_arraybool, optional

If True, return an an ‘ndarray’, else print the output.

Returns
N/A

Examples

>>> wfdb.ann2rr('sample-data/100', 'atr', as_array=False)
>>> 18
>>> 59
>>> ...
>>> 250
>>> 257
wfdb.processing.calc_mean_hr(rr, fs=None, min_rr=None, max_rr=None, rr_units='samples')

Compute mean heart rate in beats per minute, from a set of R-R intervals. Returns 0 if rr is empty.

Parameters
rrndarray

Array of R-R intervals.

fsint, float

The corresponding signal’s sampling frequency. Required if ‘input_time_units’ == ‘samples’.

min_rrfloat, optional

The minimum allowed R-R interval. Values below this are excluded when calculating the heart rate. Units are in rr_units.

max_rrfloat, optional

The maximum allowed R-R interval. Values above this are excluded when calculating the heart rate. Units are in rr_units.

rr_unitsstr, optional

The time units of the input R-R intervals. Must be one of: ‘samples’, ‘seconds’.

Returns
mean_hrfloat

The mean heart rate in beats per minute.

wfdb.processing.calc_rr(qrs_locs, fs=None, min_rr=None, max_rr=None, qrs_units='samples', rr_units='samples')

Compute R-R intervals from QRS indices by extracting the time differences.

Parameters
qrs_locsndarray

1d array of QRS locations.

fsfloat, optional

Sampling frequency of the original signal. Needed if qrs_units does not match rr_units.

min_rrfloat, optional

The minimum allowed R-R interval. Values below this are excluded from the returned R-R intervals. Units are in rr_units.

max_rrfloat, optional

The maximum allowed R-R interval. Values above this are excluded from the returned R-R intervals. Units are in rr_units.

qrs_unitsstr, optional

The time unit of qrs_locs. Must be one of: ‘samples’, ‘seconds’.

rr_unitsstr, optional

The desired time unit of the returned R-R intervals in. Must be one of: ‘samples’, ‘seconds’.

Returns
rrndarray

Array of R-R intervals.

wfdb.processing.compute_hr(sig_len, qrs_inds, fs)

Compute instantaneous heart rate from peak indices.

Parameters
sig_lenint

The length of the corresponding signal.

qrs_indsndarray

The QRS index locations.

fsint, float

The corresponding signal’s sampling frequency.

Returns
heart_ratendarray

An array of the instantaneous heart rate, with the length of the corresponding signal. Contains numpy.nan where heart rate could not be computed.

wfdb.processing.rr2ann(rr_array, record_name, extension, fs=250, as_time=False)

Creates an annotation file from the standard input, which should usually be a Numpy array of intervals in the format produced by ann2rr. (For exceptions, see the as_time parameter below.). An optional second column may be provided which gives the respective annotation mnemonic.

Parameters
rr_arrayndarray

A Numpy array consisting of the input RR intervals. If as_time is set to True, then the input should consist of times of occurences. If, the shape of the input array is ‘(n_annot,2)’, then treat the second column as the annotation mnemonic (‘N’, ‘V’, etc.). If a second column is not specified, then the default annotation will the ‘”’ which specifies a comment.

record_namestr

The record name of the WFDB annotation file. ie. for file ‘100.atr’, record_name=’100’.

extensionstr

The annotatator extension of the annotation file. ie. for file ‘100.atr’, extension=’atr’.

fsfloat, int, optional

Assume the specified sampling frequency. This option has no effect unless the as_time parameter is set to convert to samples; in this case, a sampling frequency of 250 Hz is assumed if this option is omitted.

as_timebool

Interpret the input as times of occurrence (if True), rather than as samples (if False). There is not currently a way to input RR intervals in time format between beats. For example, 0.2 seconds between beats 1->2, 0.3 seconds between beats 2->3, etc.

Returns
N/A

Examples

Using time of occurence as input: >>> import numpy as np >>> rr_array = np.array([[0.2, 0.6, 1.3], [‘V’, ‘N’, ‘V’]]).T >>> wfdb.rr2ann(rr_array, ‘test_ann’, ‘atr’, fs=100, as_time=True)

Using samples as input: >>> import numpy as np >>> rr_array = np.array([4, 17, 18, 16]) >>> wfdb.rr2ann(rr_array, ‘test_ann’, ‘atr’)

Peaks

wfdb.processing.correct_peaks(sig, peak_inds, search_radius, smooth_window_size, peak_dir='compare')

Adjust a set of detected peaks to coincide with local signal maxima.

Parameters
signdarray

The 1d signal array.

peak_indsnp array

Array of the original peak indices.

search_radiusint

The radius within which the original peaks may be shifted.

smooth_window_sizeint

The window size of the moving average filter applied on the signal. Peak distance is calculated on the difference between the original and smoothed signal.

peak_dirstr, optional

The expected peak direction: ‘up’ or ‘down’, ‘both’, or ‘compare’.

  • If ‘up’, the peaks will be shifted to local maxima.

  • If ‘down’, the peaks will be shifted to local minima.

  • If ‘both’, the peaks will be shifted to local maxima of the rectified signal.

  • If ‘compare’, the function will try both ‘up’ and ‘down’ options, and choose the direction that gives the largest mean distance from the smoothed signal.

Returns
shifted_peak_indsndarray

Array of the corrected peak indices.

wfdb.processing.find_local_peaks(sig, radius)

Find all local peaks in a signal. A sample is a local peak if it is the largest value within the <radius> samples on its left and right. In cases where it shares the max value with nearby samples, the middle sample is classified as the local peak.

Parameters
signdarray

1d numpy array of the signal.

radiusint

The radius in which to search for defining local maxima.

Returns
ndarray

The locations of all of the local peaks of the input signal.

wfdb.processing.find_peaks(sig)

Find hard peaks and soft peaks in a signal, defined as follows:

  • Hard peak: a peak that is either /or /.

  • Soft peak: a peak that is either /-or -/. In this case we define the middle as the peak.

Parameters
signp array

The 1d signal array.

Returns
hard_peaksndarray

Array containing the indices of the hard peaks.

soft_peaksndarray

Array containing the indices of the soft peaks.

Filters

wfdb.processing.sigavg(record_name, extension, pn_dir=None, return_df=False, start_range=- 0.05, stop_range=0.05, ann_type='all', start_time=0, stop_time=- 1, verbose=False)

A common problem in signal processing is to determine the shape of a recurring waveform in the presence of noise. If the waveform recurs periodically (for example, once per second) the signal can be divided into segments of an appropriate length (one second in this example), and the segments can be averaged to reduce the amplitude of any noise that is uncorrelated with the signal. Typically, noise is reduced by a factor of the square root of the number of segments included in the average. For physiologic signals, the waveforms of interest are usually not strictly periodic, however. This function averages such waveforms by defining segments (averaging windows) relative to the locations of waveform annotations. By default, all QRS (beat) annotations for the specified annotator are included.

Parameters
record_namestr

The name of the WFDB record to be read, without any file extensions. If the argument contains any path delimiter characters, the argument will be interpreted as PATH/BASE_RECORD. Both relative and absolute paths are accepted. If the pn_dir parameter is set, this parameter should contain just the base record name, and the files fill be searched for remotely. Otherwise, the data files will be searched for in the local path.

pn_dirstr, optional

Option used to stream data from Physionet. The Physionet database directory from which to find the required record files. eg. For record ‘100’ in ‘http://physionet.org/content/mitdb’ pn_dir=’mitdb’.

return_dfbool, optional

Whether to return a Pandas dataframe (True) or just print the output (False).

start_rangefloat, int, optional

Set the measurement window relative to QRS annotations. Negative values correspond to offsets that precede the annotations. The default is -0.05 seconds.

stop_rangefloat, int, optional

Set the measurement window relative to QRS annotations. Negative values correspond to offsets that precede the annotations. The default is 0.05 seconds.

ann_typelist[str], str, optional

Include annotations of the specified types only (i.e. ‘N’). Multiple types are also accepted (i.e. [‘V’,’N’]). The default is ‘all’ which means to include all QRS annotations.

start_timefloat, int, optional

Begin at the specified time in record. The default is 0 which denotes the start of the record.

stop_timefloat, int, optional

Process until the specified time in record. The default is -1 which denotes the end of the record.

verbosebool, optional

Whether to print the headers (True) or not (False).

Returns
N/APandas dataframe

If return_df is set to True, return a Pandas dataframe representing the output from the original WFDB package. This is the same content as if return_df were set to False, just in dataframe form.

QRS Detectors

class wfdb.processing.XQRS(sig, fs, conf=None)

The QRS detector class for the XQRS algorithm. The XQRS.Conf class is the configuration class that stores initial parameters for the detection. The XQRS.detect method runs the detection algorithm.

The process works as follows:

  • Load the signal and configuration parameters.

  • Bandpass filter the signal between 5 and 20 Hz, to get the filtered signal.

  • Apply moving wave integration (MWI) with a Ricker (Mexican hat) wavelet onto the filtered signal, and save the square of the integrated signal.

  • Conduct learning if specified, to initialize running parameters of noise and QRS amplitudes, the QRS detection threshold, and recent R-R intervals. If learning is unspecified or fails, use default parameters. See the docstring for the _learn_init_params method of this class for details.

  • Run the main detection. Iterate through the local maxima of the MWI signal. For each local maxima:

    • Check if it is a QRS complex. To be classified as a QRS, it must come after the refractory period, cross the QRS detection threshold, and not be classified as a T-wave if it comes close enough to the previous QRS. If successfully classified, update running detection threshold and heart rate parameters.

    • If not a QRS, classify it as a noise peak and update running parameters.

    • Before continuing to the next local maxima, if no QRS was detected within 1.66 times the recent R-R interval, perform backsearch QRS detection. This checks previous peaks using a lower QRS detection threshold.

Examples

>>> import wfdb
>>> from wfdb import processing
>>> sig, fields = wfdb.rdsamp('sample-data/100', channels=[0])
>>> xqrs = processing.XQRS(sig=sig[:,0], fs=fields['fs'])
>>> xqrs.detect()
>>> wfdb.plot_items(signal=sig, ann_samp=[xqrs.qrs_inds])
Attributes
sig1d ndarray

The input ECG signal to apply the QRS detection on.

fsint, float

The sampling frequency of the input signal.

confXQRS.Conf object, optional

The configuration object specifying signal configuration parameters. See the docstring of the XQRS.Conf class.

class Conf(hr_init=75, hr_max=200, hr_min=25, qrs_width=0.1, qrs_thr_init=0.13, qrs_thr_min=0, ref_period=0.2, t_inspect_period=0)

Initial signal configuration object for this QRS detector.

Attributes
hr_initint, float, optional

Initial heart rate in beats per minute. Used for calculating recent R-R intervals.

hr_maxint, float, optional

Hard maximum heart rate between two beats, in beats per minute. Used for refractory period.

hr_minint, float, optional

Hard minimum heart rate between two beats, in beats per minute. Used for calculating recent R-R intervals.

qrs_widthint, float, optional

Expected QRS width in seconds. Used for filter widths indirect refractory period.

qrs_thr_initint, float, optional

Initial QRS detection threshold in mV. Use when learning is False, or learning fails.

qrs_thr_minint, float, string, optional

Hard minimum detection threshold of QRS wave. Leave as 0 for no minimum.

ref_periodint, float, optional

The QRS refractory period.

t_inspect_periodint, float, optional

The period below which a potential QRS complex is inspected to see if it is a T-wave. Leave as 0 for no T-wave inspection.

detect(sampfrom=0, sampto='end', learn=True, verbose=True)

Detect QRS locations between two samples.

Parameters
sampfromint, optional

The starting sample number to run the detection on.

samptoint, optional

The final sample number to run the detection on. Set as ‘end’ to run on the entire signal.

learnbool, optional

Whether to apply learning on the signal before running the main detection. If learning fails or is not conducted, the default configuration parameters will be used to initialize these variables. See the XQRS._learn_init_params docstring for details.

verbosebool, optional

Whether to display the stages and outcomes of the detection process.

Returns
N/A
wfdb.processing.gqrs_detect(sig=None, fs=None, d_sig=None, adc_gain=None, adc_zero=None, threshold=1.0, hr=75, RRdelta=0.2, RRmin=0.28, RRmax=2.4, QS=0.07, QT=0.35, RTmin=0.25, RTmax=0.33, QRSa=750, QRSamin=130)

Detect QRS locations in a single channel ecg. Functionally, a direct port of the GQRS algorithm from the original WFDB package. Accepts either a physical signal, or a digital signal with known adc_gain and adc_zero. See the notes below for a summary of the program. This algorithm is not being developed/supported.

Parameters
sig1d numpy array, optional

The input physical signal. The detection algorithm which replicates the original, works using digital samples, and this physical option is provided as a convenient interface. If this is the specified input signal, automatic adc is performed using 24 bit precision, to obtain the d_sig, adc_gain, and adc_zero parameters. There may be minor differences in detection results (ie. an occasional 1 sample difference) between using sig and d_sig. To replicate the exact output of the original GQRS algorithm, use the d_sig argument instead.

fsint, float, optional

The sampling frequency of the signal.

d_sig1d numpy array, optional

The input digital signal. If this is the specified input signal rather than sig, the adc_gain and adc_zero parameters must be specified.

adc_gainint, float, optional

The analogue to digital gain of the signal (the number of adus per physical unit).

adc_zeroint, optional

The value produced by the ADC given a 0 Volt input.

thresholdint, float, optional

The relative amplitude detection threshold. Used to initialize the peak and QRS detection threshold.

hrint, float, optional

Typical heart rate, in beats per minute.

RRdeltaint, float, optional

Typical difference between successive RR intervals in seconds.

RRminint, float, optional

Minimum RR interval (“refractory period”), in seconds.

RRmaxint, float, optional

Maximum RR interval, in seconds. Thresholds will be adjusted if no peaks are detected within this interval.

QSint, float, optional

Typical QRS duration, in seconds.

QTint, float, optional

Typical QT interval, in seconds.

RTminint, float, optional

Minimum interval between R and T peaks, in seconds.

RTmaxint, float, optional

Maximum interval between R and T peaks, in seconds.

QRSaint, float, optional

Typical QRS peak-to-peak amplitude, in microvolts.

QRSaminint, float, optional

Minimum QRS peak-to-peak amplitude, in microvolts.

Returns
qrs_locsndarray

Detected QRS locations.

Notes

This function should not be used for signals with fs <= 50Hz.

The algorithm theoretically works as follows:

  • Load in configuration parameters. They are used to set/initialize the:

    • allowed R-R interval limits (fixed)

    • initial recent R-R interval (running)

    • QRS width, used for detection filter widths (fixed)

    • allowed R-T interval limits (fixed)

    • initial recent R-T interval (running)

    • initial peak amplitude detection threshold (running)

    • initial QRS amplitude detection threshold (running)

    • Note: this algorithm does not normalize signal amplitudes, and hence is highly dependent on configuration amplitude parameters.

  • Apply trapezoid low-pass filtering to the signal.

  • Convolve a QRS matched filter with the filtered signal.

  • Run the learning phase using a calculated signal length: detect QRS and non-qrs peaks as in the main detection phase, without saving the QRS locations. During this phase, running parameters of recent intervals and peak/qrs thresholds are adjusted.

  • Run the detection:

    if a sample is bigger than its immediate neighbors and larger than the peak detection threshold, it is a peak.

    if it is further than RRmin from the previous QRS, and is a primary peak.

    if it is further than 2 standard deviations from the previous QRS, do a backsearch for a missed low amplitude beat.

    return the primary peak between the current sample and the previous QRS if any.

    if it surpasses the QRS threshold, it is a QRS complex

    save the QRS location. update running R-R interval and QRS amplitude parameters. look for the QRS complex’s T-wave and mark it if found.

    else if it is not a peak.

    lower the peak detection threshold if the last peak found was more than RRmax ago, and not already at its minimum.

A peak is secondary if there is a larger peak within its neighborhood (time +- rrmin), or if it has been identified as a T-wave associated with a previous primary peak. A peak is primary if it is largest in its neighborhood, or if the only larger peaks are secondary.

The above describes how the algorithm should theoretically work, but there are bugs which make the program contradict certain parts of its supposed logic. A list of issues from the original c, code and hence this python implementation can be found here:

https://github.com/bemoody/wfdb/issues/17

Examples

>>> import numpy as np
>>> import wfdb
>>> from wfdb import processing
>>> # Detect using a physical input signal
>>> record = wfdb.rdrecord('sample-data/100', channels=[0])
>>> qrs_locs = processing.gqrs_detect(record.p_signal[:,0], fs=record.fs)
>>> # Detect using a digital input signal
>>> record_2 = wfdb.rdrecord('sample-data/100', channels=[0], physical=False)
>>> qrs_locs_2 = processing.gqrs_detect(d_sig=record_2.d_signal[:,0],
                                        fs=record_2.fs,
                                        adc_gain=record_2.adc_gain[0],
                                        adc_zero=record_2.adc_zero[0])
wfdb.processing.xqrs_detect(sig, fs, sampfrom=0, sampto='end', conf=None, learn=True, verbose=True)

Run the ‘xqrs’ QRS detection algorithm on a signal. See the docstring of the XQRS class for algorithm details.

Parameters
signdarray

The input ECG signal to apply the QRS detection on.

fsint, float

The sampling frequency of the input signal.

sampfromint, optional

The starting sample number to run the detection on.

samptostr

The final sample number to run the detection on. Set as ‘end’ to run on the entire signal.

confXQRS.Conf object, optional

The configuration object specifying signal configuration parameters. See the docstring of the XQRS.Conf class.

learnbool, optional

Whether to apply learning on the signal before running the main detection. If learning fails or is not conducted, the default configuration parameters will be used to initialize these variables.

verbosebool, optional

Whether to display the stages and outcomes of the detection process.

Returns
qrs_indsndarray

The indices of the detected QRS complexes.

Examples

>>> import wfdb
>>> from wfdb import processing
>>> sig, fields = wfdb.rdsamp('sample-data/100', channels=[0])
>>> qrs_inds = processing.xqrs_detect(sig=sig[:,0], fs=fields['fs'])

Annotation Evaluators

class wfdb.processing.Comparitor(ref_sample, test_sample, window_width, signal=None)

The class to implement and hold comparisons between two sets of annotations. See methods compare, print_summary and plot.

Examples

>>> import wfdb
>>> from wfdb import processing
>>> sig, fields = wfdb.rdsamp('sample-data/100', channels=[0])
>>> ann_ref = wfdb.rdann('sample-data/100','atr')
>>> xqrs = processing.XQRS(sig=sig[:,0], fs=fields['fs'])
>>> xqrs.detect()
>>> comparitor = processing.Comparitor(ann_ref.sample[1:],
                                       xqrs.qrs_inds,
                                       int(0.1 * fields['fs']),
                                       sig[:,0])
>>> comparitor.compare()
>>> comparitor.print_summary()
>>> comparitor.plot()
Attributes
ref_samplendarray

An array of the reference sample locations.

test_samplendarray

An array of the comparison sample locations.

window_widthint

The width of the window.

signal1d numpy array, optional

The signal array the annotation samples are labelling. Only used for plotting.

compare()

Main comparison function. Note: Make sure to be able to handle these ref/test scenarios:

N/A

Returns
N/A
plot(sig_style='', title=None, figsize=None, return_fig=False)

Plot the comparison of two sets of annotations, possibly overlaid on their original signal.

Parameters
sig_stylestr, optional

The matplotlib style of the signal

titlestr, optional

The title of the plot

figsize: tuple, optional

Tuple pair specifying the width, and height of the figure. It is the’figsize’ argument passed into matplotlib.pyplot’s figure function.

return_figbool, optional

Whether the figure is to be returned as an output argument.

Returns
figmatplotlib figure object

The figure information for the plot.

axmatplotlib axes object

The axes information for the plot.

print_summary()

Print summary metrics of the annotation comparisons.

Parameters
N/A
Returns
N/A
wfdb.processing.benchmark_mitdb(detector, verbose=False, print_results=False)

Benchmark a QRS detector against mitdb’s records.

Parameters
detectorfunction

The detector function.

verbosebool, optional

The verbose option of the detector function.

print_resultsbool, optional

Whether to print the overall performance, and the results for each record.

Returns
comparitorsdictionary

Dictionary of Comparitor objects run on the records, keyed on the record names.

sensitivityfloat

Aggregate sensitivity.

positive_predictivityfloat

Aggregate positive_predictivity.

Notes

TODO: - remove non-qrs detections from reference annotations - allow kwargs

Examples

>>> import wfdb
>> from wfdb.processing import benchmark_mitdb, xqrs_detect
>>> comparitors, spec, pp = benchmark_mitdb(xqrs_detect)
wfdb.processing.compare_annotations(ref_sample, test_sample, window_width, signal=None)

Compare a set of reference annotation locations against a set of test annotation locations. See the Comparitor class docstring for more information.

Parameters
ref_sample1d numpy array

Array of reference sample locations.

test_sample1d numpy array

Array of test sample locations to compare.

window_widthint

The maximum absolute difference in sample numbers that is permitted for matching annotations.

signal1d numpy array, optional

The original signal of the two annotations. Only used for plotting.

Returns
comparitorComparitor object

Object containing parameters about the two sets of annotations.

Examples

>>> import wfdb
>>> from wfdb import processing
>>> sig, fields = wfdb.rdsamp('sample-data/100', channels=[0])
>>> ann_ref = wfdb.rdann('sample-data/100','atr')
>>> xqrs = processing.XQRS(sig=sig[:,0], fs=fields['fs'])
>>> xqrs.detect()
>>> comparitor = processing.compare_annotations(ann_ref.sample[1:],
                                                xqrs.qrs_inds,
                                                int(0.1 * fields['fs']),
                                                sig[:,0])
>>> comparitor.print_summary()
>>> comparitor.plot()