This Notebook contains the code used for data processing, statistical analysis and visualization described in the following paper:
Belteki G, Morley CJ. Frequency, duration and cause of ventilator alarms on a neonatal intensive care unit. Arch Dis Child Fetal Neonatal Ed. 2018 Jul;103(4):F307-F311. doi: 10.1136/archdischild-2017-313493. Epub 2017 Oct 27. PubMed PMID: 29079651.
Link to the paper: https://fn.bmj.com/content/103/4/F307.long
Contact: gusztav.belteki@addenbrookes.nhs.uk; gbelteki@aol.com
In [ ]:
import IPython
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import os
import sys
import pickle
import scipy as sp
from scipy import stats
from pandas import Series, DataFrame
from datetime import datetime, timedelta
%matplotlib inline
matplotlib.style.use('classic')
matplotlib.rcParams['figure.facecolor'] = 'w'
pd.set_option('display.max_rows', 100)
pd.set_option('display.max_columns', 100)
pd.set_option('mode.chained_assignment', None)
In [ ]:
print("Python version: {}".format(sys.version))
print("IPython version: {}".format(IPython.__version__))
print("pandas version: {}".format(pd.__version__))
print("matplotlib version: {}".format(matplotlib.__version__))
print("NumPy version: {}".format(np.__version__))
print("SciPy version: {}".format(sp.__version__))
In [ ]:
from gb_loader import *
from gb_stats import *
from gb_transform import *
In [ ]:
# Topic of the Notebook which will also be the name of the subfolder containing results
TOPIC = 'alarms_2'
# Name of the external hard drive
DRIVE = 'GUSZTI'
# Directory containing clinical and blood gas data
CWD = '/Users/guszti/ventilation_data'
# Directory on external drive to read the ventilation data from
DIR_READ = '/Volumes/%s/ventilation_data' % DRIVE
# Directory to write results and selected images to
if not os.path.isdir('%s/%s/%s' % (CWD, 'Analyses', TOPIC)):
os.makedirs('%s/%s/%s' % (CWD, 'Analyses', TOPIC))
DIR_WRITE = '%s/%s/%s' % (CWD, 'Analyses', TOPIC)
# Images and raw data will be written on an external hard drive
if not os.path.isdir('/Volumes/%s/data_dump/%s' % (DRIVE, TOPIC)):
os.makedirs('/Volumes/%s/data_dump/%s' % (DRIVE, TOPIC))
DATA_DUMP = '/Volumes/%s/data_dump/%s' % (DRIVE, TOPIC)
In [ ]:
os.chdir(CWD)
os.getcwd()
In [ ]:
DIR_READ
In [ ]:
DIR_WRITE
In [ ]:
DATA_DUMP
In [ ]:
# One recording from each patient, all of them 24 hours old or longer
# The sub folders containing the individual recordings have the same names within cwd
recordings = ['DG001', 'DG002_1', 'DG003', 'DG004', 'DG005_1', 'DG006_2', 'DG007', 'DG008', 'DG009', 'DG010',
'DG011', 'DG013', 'DG014', 'DG015', 'DG016', 'DG017', 'DG018_1', 'DG020',
'DG021', 'DG022', 'DG023', 'DG025', 'DG026', 'DG027', 'DG028', 'DG029', 'DG030',
'DG031', 'DG032_2', 'DG033', 'DG034', 'DG035', 'DG037', 'DG038_1', 'DG039', 'DG040_1', 'DG041',
'DG042', 'DG043', 'DG044', 'DG045', 'DG046_2', 'DG047', 'DG048', 'DG049', 'DG050']
In [ ]:
clinical_details = pd.read_excel('%s/data_grabber_patient_data_combined.xlsx' % CWD)
clinical_details.index = clinical_details['Recording']
In [ ]:
clinical_details.info()
In [ ]:
current_weights = {}
for recording in recordings:
current_weights[recording] = clinical_details.loc[recording, 'Current weight' ] / 1000
In [ ]:
slow_measurements = {}
for recording in recordings:
flist = os.listdir('%s/%s' % (DIR_READ, recording))
flist = [file for file in flist if not file.startswith('.')] # There are some hidden
# files on the hard drive starting with '.'; this step is necessary to ignore them
files = slow_measurement_finder(flist)
print('Loading recording %s' % recording)
print(files)
fnames = ['%s/%s/%s' % (DIR_READ, recording, filename) for filename in files]
slow_measurements[recording] = data_loader(fnames)
In [ ]:
# 46 recordings from 46 patients (4 recordings excluded as they were < 24 hours lon)
len(slow_measurements)
In [ ]:
for recording in recordings:
try:
a = slow_measurements[recording]
a['VT_kg'] = a['5001|VT [mL]'] / current_weights[recording]
a['VTi_kg'] = a['5001|VTi [mL]'] / current_weights[recording]
a['VTe_kg'] = a['5001|VTe [mL]'] / current_weights[recording]
a['VTmand_kg'] = a['5001|VTmand [mL]'] / current_weights[recording]
a['VTspon_kg'] = a['5001|VTspon [mL]'] / current_weights[recording]
a['VTimand_kg'] = a['5001|VTimand [mL]'] / current_weights[recording]
a['VTemand_kg'] = a['5001|VTemand [mL]'] / current_weights[recording]
a['VTispon_kg'] = a['5001|VTispon [mL]'] / current_weights[recording]
a['VTespon_kg'] = a['5001|VTespon [mL]'] / current_weights[recording]
except KeyError:
# print('%s does not have all of the parameters' % recording)
pass
In [ ]:
for recording in recordings:
try:
a = slow_measurements[recording]
a['VThf_kg'] = a['5001|VThf [mL]'] / current_weights[recording]
a['DCO2_corr_kg'] = a['5001|DCO2 [10*mL^2/s]'] * 10 / (current_weights[recording]) ** 2
except KeyError:
# print('%s does not have all of the parameters' % recording)
pass
In [ ]:
for recording in recordings:
try:
a = slow_measurements[recording]
a['MV_kg'] = a['5001|MV [L/min]'] / current_weights[recording]
a['MVi_kg'] = a['5001|MVi [L/min]'] / current_weights[recording]
a['MVe_kg'] = a['5001|MVe [L/min]'] / current_weights[recording]
a['MVemand_kg'] = a['5001|MVemand [L/min]'] / current_weights[recording]
a['MVespon_kg'] = a['5001|MVespon [L/min]'] / current_weights[recording]
a['MVleak_kg'] = a['5001|MVleak [L/min]'] / current_weights[recording]
except KeyError:
# print('%s does not have all of the parameters' % recording)
pass
In [ ]:
# 1/sec data are retrieved in two parts which need to be joined
# This resampling steps combines the two parts
for recording in recordings:
slow_measurements[recording] = slow_measurements[recording].resample('1S').mean()
In [ ]:
# Example
slow_measurements['DG003'].head();
In [ ]:
len(recordings)
In [ ]:
rec1 = recordings[:15]; rec2 = recordings[15:30]; rec3 = recordings[30:40]; rec4 = recordings[40:]
In [ ]:
# Time stamps are obtained from 'slow measurements'
recording_duration = {}
for recording in recordings:
recording_duration[recording] = slow_measurements[recording].index[-1] - slow_measurements[recording].index[0]
In [ ]:
recording_duration_seconds = {}
recording_duration_hours = {}
for recording in recordings:
temp = recording_duration[recording]
recording_duration_seconds[recording] = temp.total_seconds()
recording_duration_hours[recording] = temp.total_seconds() / 3600
In [ ]:
v = list(range(1, len(recordings)+1))
w = [value for key, value in sorted(recording_duration_hours.items()) if key in recordings]
In [ ]:
fig = plt.figure()
fig.set_size_inches(20, 10)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
ax1 = fig.add_subplot(1, 1, 1);
ax1.bar(v, w, color = 'blue')
plt.xlabel("Recordings", fontsize = 22)
plt.ylabel("Hours", fontsize = 22)
plt.title("Recording periods" , fontsize = 22)
plt.yticks(fontsize = 22)
plt.xticks([i+1.5 for i, _ in enumerate(recordings)], recordings, fontsize = 22, rotation = 'vertical');
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'recording_durations.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
recording_times_frame = DataFrame([recording_duration, recording_duration_hours, recording_duration_seconds],
index = ['days', 'hours', 'seconds'])
In [ ]:
recording_times_frame
In [ ]:
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'recording_periods.xlsx'))
recording_times_frame.to_excel(writer,'rec_periods')
writer.save()
In [ ]:
vent_settings = {}
for recording in recordings:
flist = os.listdir('%s/%s' % (DIR_READ, recording))
flist = [file for file in flist if not file.startswith('.')] # There are some hidden
# files on the hard drive starting with '.'; this step is necessary to ignore them
files = slow_setting_finder(flist)
# print('Loading recording %s' % recording)
# print(files)
fnames = ['%s/%s/%s' % (DIR_READ, recording, filename) for filename in files]
vent_settings[recording] = data_loader(fnames)
In [ ]:
# remove less important ventilator settings to simplify the table
vent_settings_selected = {}
for recording in recordings:
vent_settings_selected[recording] = vent_settings_cleaner(vent_settings[recording])
In [ ]:
# Create a another dictionary of Dataframes wit some of the ventilation settings (set VT, set RR, set Pmax)
lsts = [(['VT_weight'], ['VTi', 'VThf']), (['RR_set'], ['RR']), (['Pmax'], ['Pmax', 'Ampl hf max'])]
vent_settings_2 = {}
for recording in recordings:
frmes = []
for name, pars in lsts:
if pars in [['VTi', 'VThf']]:
ind = []
val = []
for index, row in vent_settings_selected[recording].iterrows():
if row['Id'] in pars:
ind.append(index)
val.append(row['Value New'] / current_weights[recording])
frmes.append(DataFrame(val, index = ind, columns = name))
else:
ind = []
val = []
for index, row in vent_settings_selected[recording].iterrows():
if row['Id'] in pars:
ind.append(index)
val.append(row['Value New'])
frmes.append(DataFrame(val, index = ind, columns = name))
vent_settings_2[recording] = pd.concat(frmes)
vent_settings_2[recording].drop_duplicates(inplace = True)
In [ ]:
vent_modes = {}
for recording in recordings:
flist = os.listdir('%s/%s' % (DIR_READ, recording))
flist = [file for file in flist if not file.startswith('.')] # There are some hidden
# files on the hard drive starting with '.'; this step is necessary to ignore them
files = slow_text_finder(flist)
# print('Loading recording %s' % recording)
# print(files)
fnames = ['%s/%s/%s' % (DIR_READ, recording, filename) for filename in files]
vent_modes[recording] = data_loader(fnames)
In [ ]:
# remove less important ventilator mode settings to simplify the table
vent_modes_selected = {}
for recording in recordings:
vent_modes_selected[recording] = vent_mode_cleaner(vent_modes[recording])
In [ ]:
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'ventilator_settings.xlsx'))
for recording in recordings:
vent_settings[recording].to_excel(writer,'%s' % recording)
writer.save()
In [ ]:
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'ventilator_settings_selected.xlsx'))
for recording in recordings:
vent_settings_selected[recording].to_excel(writer,'%s' % recording)
writer.save()
In [ ]:
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'ventilator_settings_2.xlsx'))
for recording in recordings:
vent_settings_2[recording].to_excel(writer,'%s' % recording)
writer.save()
In [ ]:
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'ventilator_modes.xlsx'))
for recording in recordings:
vent_modes[recording].to_excel(writer,'%s' % recording)
writer.save()
In [ ]:
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'ventilator_modes_selected.xlsx'))
for recording in recordings:
vent_modes_selected[recording].to_excel(writer,'%s' % recording)
writer.save()
In [ ]:
alarm_settings = {}
for recording in recordings:
flist = os.listdir('%s/%s' % (DIR_READ, recording))
flist = [file for file in flist if not file.startswith('.')] # There are some hidden
# files on the hard drive starting with '.'; this step is necessary to ignore them
files = alarm_setting_finder(flist)
# print('Loading recording %s' % recording)
# print(files)
fnames = ['%s/%s/%s' % (DIR_READ, recording, filename) for filename in files]
alarm_settings[recording] = data_loader(fnames)
In [ ]:
# Remove etCO2 limits which were not used
alarm_settings_selected = {}
for recording in recordings:
alarm_settings_selected[recording] = alarm_setting_cleaner(alarm_settings[recording])
In [ ]:
# Create a another dictionary of Dataframes with some of the alarm settings
lsts = [(['MV_high_weight'], ['MVe_HL']), (['MV_low_weight'], ['MVe_LL']),
(['PIP_high'], ['PIP_HL']), (['RR_high'], ['RR_HL'])]
alarm_settings_2 = {}
for recording in recordings:
frmes = []
for name, pars in lsts:
if pars in [['MVe_HL'], ['MVe_LL']]:
ind = []
val = []
for index, row in alarm_settings_selected[recording].iterrows():
if row['Id'] in pars:
ind.append(index)
val.append(row['Value New'] / current_weights[recording])
frmes.append(DataFrame(val, index = ind, columns = name))
else:
ind = []
val = []
for index, row in alarm_settings_selected[recording].iterrows():
if row['Id'] in pars:
ind.append(index)
val.append(row['Value New'])
frmes.append(DataFrame(val, index = ind, columns = name))
alarm_settings_2[recording] = pd.concat(frmes)
alarm_settings_2[recording].drop_duplicates(inplace = True)
In [ ]:
# Write DataFrames containing alarm settings to a multisheet Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'alarm_settings.xlsx'))
for recording in recordings:
alarm_settings[recording].to_excel(writer,'%s' % recording)
writer.save()
In [ ]:
# Write DataFrames containing alarm settings to a multisheet Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'alarm_settings_2.xlsx'))
for recording in recordings:
alarm_settings_2[recording].to_excel(writer,'%s' % recording)
writer.save()
In [ ]:
alarm_states = {}
for recording in recordings:
flist = os.listdir('%s/%s' % (DIR_READ, recording))
flist = [file for file in flist if not file.startswith('.')] # There are some hidden
# files on the hard drive starting with '.'; this step is necessary to ignore them
files = alarm_state_finder(flist)
# print('Loading recording %s' % recording)
# print(files)
fnames = ['%s/%s/%s' % (DIR_READ, recording, filename) for filename in files]
alarm_states[recording] = data_loader(fnames)
In [ ]:
# Write DataFrames containing alarm states to a multisheet Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'alarm_states.xlsx'))
for recording in recordings:
alarm_states[recording].to_excel(writer,'%s' % recording)
writer.save()
In [ ]:
total_recording_time = timedelta(0)
for recording in recordings:
total_recording_time += recording_duration[recording]
In [ ]:
total_recording_time
In [ ]:
mean_recording_time = total_recording_time / len(recordings)
mean_recording_time
In [ ]:
# Define function to retrieve alarm events from alarm timing data
def alarm_events_calculator(dframe, al):
'''
DataFrame, str -> DataFrame
dframe: DataFrame containing alarm states
al: alarm category (string)
Returns a pd.DataFrame object with the time stamps when the alarm went off and the duration (in seconds)
of the alarm for alarm 'al' in recording 'rec'
'''
alarms = dframe
alarm = alarms[alarms.Name == al]
length = len(alarm)
delta = np.array([(alarm.Date_Time[i] - alarm.Date_Time[i-1]).total_seconds()
for i in range(1, length) if alarm['State New'][i] == 'NotActive' and alarm['State New'][i-1] == 'Active'])
stamp = np.array([alarm.index[i-1]
for i in range(1, length) if alarm['State New'][i] == 'NotActive' and alarm['State New'][i-1] == 'Active'])
data = {'duration_seconds': delta, 'time_went_off': stamp,}
alarm_t = DataFrame(data, columns = ['time_went_off', 'duration_seconds'])
return alarm_t
Using the files containing the alarm states, for each alarm category in each recording create a DataFrame with the timestamps the alarm went off and the duration of the alarm and store them in a dictionary of dictionaries
In [ ]:
# Create a list of alarms occurring during each recording
alarm_list = {}
for recording in recordings:
alarm_list[recording] = sorted(set(alarm_states[recording].Name))
In [ ]:
alarm_events = {}
for recording in recordings:
alarm_events[recording] = {}
for alarm in alarm_list[recording]:
alarm_events[recording][alarm] = alarm_events_calculator(alarm_states[recording], alarm)
In [ ]:
# Write Dataframes containing the alarm events in Excel files,
# one Excel file for each recording
for recording in recordings:
writer = pd.ExcelWriter('%s/%s%s' % (DIR_WRITE, recording, '_alarm_events.xlsx'))
for alarm in alarm_list[recording]:
alarm_events[recording][alarm].to_excel(writer, alarm[:20])
writer.save()
In [ ]:
def alarm_stats_calculator(dframe, rec, al):
'''
dframe: DataFrame containing alarm events
rec: recording (string)
al: alarm (string)
Returns detailed statistics about a particular alarm (al) in a particular recording (rec);
- number of times alarm went off and its value normalized to 24 hour periods
- mean, median, standard deviation, mean absolute deviation, minimum, 25th centile, 75th centile, maximum
time period when the alarm was off
- the total amount of time the alarm was off and its relative value in percent as the total recording time
'''
alarm = dframe[al].duration_seconds
return (alarm.size, round((alarm.size / (recording_duration_hours[rec] / 24)), 1),
round(alarm.mean() , 1), round(alarm.median(), 1), round(alarm.std(), 1), round(alarm.min() , 1),
round(alarm.quantile(0.25), 1), round(alarm.quantile(0.75), 1), round(alarm.max(), 1),
round(alarm.sum(), 1), round(alarm.sum() * 100 / recording_duration_seconds[rec] ,3))
In [ ]:
alarm_stats = {}
for recording in recordings:
alarm_stats[recording] = {}
for alarm in alarm_list[recording]:
data = alarm_stats_calculator(alarm_events[recording], recording, alarm)
frame = DataFrame([data], columns = ['number of events', 'number of event per 24h',
'mean duration (s)', 'median duration (s)', 'SD duration (s)',
'miminum duration (s)',
'duration 25th centile (s)', 'duration 75th centile (s)',
'maximum duration (s)', 'cumulative duration (s)',
'percentage of recording length (%)'], index = [alarm])
alarm_stats[recording][alarm] = frame
In [ ]:
# Write descriptive statistics in a multisheet Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'alarm_stats.xlsx'))
for recording in recordings:
stats = []
for alarm in alarm_stats[recording]:
stats.append(alarm_stats[recording][alarm])
stats_all = pd.concat(stats)
stats_all.to_excel(writer, recording)
writer.save()
In [ ]:
# Generates a plot with the cumulative times (in seconds) of the various alarm occurring during recording (rec).
# Displays the plot
def alarm_plot_1(rec):
fig = plt.figure()
fig.set_size_inches(25, 8)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1)
xs = [i + 0.1 for i, _ in enumerate(alarm_list[rec])]
stats = []
for alarm in alarm_list[rec]:
stats.append(alarm_stats[rec][alarm]['cumulative duration (s)'])
stats_all = pd.concat(stats)
plt.barh(xs, stats_all, color = 'red')
plt.xlabel("seconds", fontsize = 24)
plt.title("Recording %s : How long was the alarm active over the %d seconds of recording?" % (rec,
recording_duration_seconds[rec]), fontsize = 22)
plt.yticks([i + 0.5 for i, _ in enumerate(alarm_list[rec])], alarm_list[rec], fontsize = 22)
plt.xticks(fontsize = 20)
In [ ]:
# Generates a plot with the cumulative times (in seconds) of the various alarm occurring during recording (rec).
# Does not displays the plot but write it into a jpg file.
# NB: the resolution of the image is only 100 dpi - for publication quality higher is needed
def alarm_plot_1_write(rec):
fig = plt.figure()
fig.set_size_inches(25, 8)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1)
xs = [i + 0.1 for i, _ in enumerate(alarm_list[rec])]
stats = []
for alarm in alarm_list[rec]:
stats.append(alarm_stats[rec][alarm]['cumulative duration (s)'])
stats_all = pd.concat(stats)
plt.barh(xs, stats_all, color = 'red')
plt.xlabel("seconds", fontsize = 24)
plt.title("Recording %s : How long was the alarm active over the %d seconds of recording?" % (rec,
recording_duration_seconds[rec]), fontsize = 22)
plt.yticks([i + 0.5 for i, _ in enumerate(alarm_list[rec])], alarm_list[rec], fontsize = 22)
plt.xticks(fontsize = 20)
fig.savefig('%s/%s_%s.jpg' % (dir_write, 'alarm_durations_1', rec), dpi=100, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
plt.close(fig)
In [ ]:
# Generates a plot with the cumulative times (expressed as percentage of the total recording time)
# of the various alarm occurring during recording (rec).
# Displays the plot
def alarm_plot_2(rec):
fig = plt.figure()
fig.set_size_inches(25, 8)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1)
xs = [i + 0.1 for i, _ in enumerate(alarm_list[rec])]
stats = []
for alarm in alarm_list[rec]:
stats.append(alarm_stats[rec][alarm]['percentage of recording length (%)'])
stats_all = pd.concat(stats)
plt.barh(xs, stats_all, color = 'red')
plt.xlabel("% of total recording time", fontsize = 24)
plt.title("Recording %s: How long the alarm active over the %s hours of recording?" % (rec,
str(recording_duration[rec])), fontsize = 22)
plt.yticks([i + 0.5 for i, _ in enumerate(alarm_list[rec])], alarm_list[rec], fontsize = 22)
plt.xticks(fontsize = 20)
In [ ]:
# Generates a plot with the cumulative times (expressed as percentage of the total recording time)
# of the various alarm occurring during recording (rec).
# Does not displays the plot but write it into a jpg file.
# NB: the resolution of the image is only 100 dpi - for publication quality higher is needed
def alarm_plot_2_write(rec):
fig = plt.figure()
fig.set_size_inches(25, 8)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1)
xs = [i + 0.1 for i, _ in enumerate(alarm_list[rec])]
stats = []
for alarm in alarm_list[rec]:
stats.append(alarm_stats[rec][alarm]['percentage of recording length (%)'])
stats_all = pd.concat(stats)
plt.barh(xs, stats_all, color = 'red')
plt.xlabel("% of total recording time", fontsize = 24)
plt.title("Recording %s: How long the alarm active over the %s hours of recording?" % (rec,
str(recording_duration[rec])), fontsize = 22)
plt.yticks([i + 0.5 for i, _ in enumerate(alarm_list[rec])], alarm_list[rec], fontsize = 22)
plt.xticks(fontsize = 20)
fig.savefig('%s/%s_%s.jpg' % (dir_write, 'alarm_durations_2', rec), dpi=100, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
plt.close(fig)
In [ ]:
# Displays the individual alarm events of the recording (rec) along the time axis
# Displays the plot
def alarm_plot_3(rec):
alarm_state = alarm_states[rec]
numbered = Series(np.zeros(len(alarm_state)), index = alarm_state.index)
for i in range(1, len(alarm_state)):
if alarm_state.iloc[i]['State New'] == 'Active':
numbered[i] = alarm_list[rec].index(alarm_state.iloc[i]['Id']) + 1
fig = plt.figure()
fig.set_size_inches(17, 8)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.plot(alarm_state.index, numbered, '|', color = 'red', markersize = 16, markeredgewidth = 1 )
plt.xlabel("Time", fontsize = 20)
plt.title("Alarm events during recording %s" % rec , fontsize = 24)
plt.yticks([i+1 for i, _ in enumerate(alarm_list[rec])], alarm_list[rec], fontsize = 18);
plt.xticks(fontsize = 14, rotation = 30)
plt.ylim(0.5, len(alarm_list[rec]) + 0.5);
In [ ]:
# Displays the individual alarm events of recording (rec) along the time axis
# Does not displays the plot but write it into a jpg file.
# NB: the resolution of the image is only 100 dpi - for publication quality higher is needed
def alarm_plot_3_write(rec):
alarm_state = alarm_states[rec]
numbered = Series(np.zeros(len(alarm_state)), index = alarm_state.index)
for i in range(1, len(alarm_state)):
if alarm_state.iloc[i]['State New'] == 'Active':
numbered[i] = alarm_list[rec].index(alarm_state.iloc[i]['Id']) + 1
fig = plt.figure()
fig.set_size_inches(17, 8)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.plot(alarm_state.index, numbered, '|', color = 'red', markersize = 16, markeredgewidth = 1 )
plt.xlabel("Time", fontsize = 20)
plt.title("Alarm events during recording %s" % rec , fontsize = 24)
plt.yticks([i+1 for i, _ in enumerate(alarm_list[rec])], alarm_list[rec], fontsize = 18);
plt.xticks(fontsize = 14, rotation = 30)
plt.ylim(0.5, len(alarm_list[rec]) + 0.5)
fig.savefig('%s/%s_%s.pdf' % (dir_write, 'individual_alarms', rec), dpi=100, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='pdf',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
plt.close(fig)
In [ ]:
alarm_plot_1('DG032_2')
In [ ]:
alarm_plot_2('DG032_2')
In [ ]:
alarm_plot_3('DG032_2')
In [ ]:
total_alarm_number_recordings = {} # dictionary containing the total number of alarm events in each recording
for recording in recordings:
total = 0
for alarm in alarm_list[recording]:
total += len(alarm_events[recording][alarm].index)
total_alarm_number_recordings[recording] = total
In [ ]:
total_alarm_number_recordings_24H = {} # dictionary containing the total number of alarm events in each recording
# corrected for 24 hour period
for recording in recordings:
total_alarm_number_recordings_24H[recording] = (total_alarm_number_recordings[recording] /
(recording_duration[recording].total_seconds() / 86400))
In [ ]:
alarm_durations_recordings = {} # a dictionary of Series. Each series contains all the alarm durations of a recording
for recording in recordings:
durations = []
for alarm in alarm_list[recording]:
durations.append(alarm_events[recording][alarm]['duration_seconds'])
durations = pd.concat(durations)
alarm_durations_recordings[recording] = durations
In [ ]:
# Dictionaries containing various descriptive statistics for each recording
mean_alarm_duration_recordings = {}
median_alarm_duration_recordings = {}
sd_alarm_duration_recordings = {}
mad_alarm_duration_recordings = {}
min_alarm_duration_recordings = {}
pc25_alarm_duration_recordings = {}
pc75_alarm_duration_recordings = {}
max_alarm_duration_recordings = {}
In [ ]:
for recording in recordings:
mean_alarm_duration_recordings[recording] = round(alarm_durations_recordings[recording].mean(), 4)
median_alarm_duration_recordings[recording] = round(alarm_durations_recordings[recording].median(), 4)
sd_alarm_duration_recordings[recording] = round(alarm_durations_recordings[recording].std(), 4)
mad_alarm_duration_recordings[recording] = round(alarm_durations_recordings[recording].mad(), 4)
min_alarm_duration_recordings[recording] = round(alarm_durations_recordings[recording].min(), 4)
pc25_alarm_duration_recordings[recording] = round(alarm_durations_recordings[recording].quantile(0.25), 4)
pc75_alarm_duration_recordings[recording] = round(alarm_durations_recordings[recording].quantile(0.75), 4)
max_alarm_duration_recordings[recording] = round(alarm_durations_recordings[recording].max(), 4)
In [ ]:
# Create DataFrame containing cumulative alarm statistics for each recording
alarm_stats_cum_rec = DataFrame([total_alarm_number_recordings,
total_alarm_number_recordings_24H,
mean_alarm_duration_recordings,
median_alarm_duration_recordings,
sd_alarm_duration_recordings,
mad_alarm_duration_recordings,
min_alarm_duration_recordings,
pc25_alarm_duration_recordings,
pc75_alarm_duration_recordings,
max_alarm_duration_recordings],
index = ['count', 'count per 24h', 'mean duration (sec)', 'median duration (sec)', 'sd duration (sec)',
'mad duration (sec)', 'min duration (sec)', '25th cent duration (sec)', '75th cent duration (sec)',
'max duration (sec)'])
In [ ]:
alarm_stats_cum_rec.round(2)
In [ ]:
# Write statistics to Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'alarm_stats_cum_rec.xlsx'))
alarm_stats_cum_rec.round(2).to_excel(writer, 'cumulative_stats')
writer.save()
In [ ]:
# Plot the absolute number of alarm events for each recording
fig = plt.figure()
fig.set_size_inches(12, 12)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(recordings)+1)), alarm_stats_cum_rec.loc['count', :], color = 'blue')
plt.ylabel("Recordings", fontsize = 22)
plt.xlabel("", fontsize = 22)
plt.title("Number of alarm events" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(recordings)], recordings, rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'number_events_rec.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Plot the number of alarm events in each recording normalised for 24 hour periods
fig = plt.figure()
fig.set_size_inches(12, 12)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(recordings)+1)), alarm_stats_cum_rec.loc['count per 24h', :], color = 'blue')
plt.ylabel("Recordings", fontsize = 22)
plt.xlabel("", fontsize = 22)
plt.title("Number of alarm events per 24 hours" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(recordings)], recordings, rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'number_events_24H_rec.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Median duration of alarm events
fig = plt.figure()
fig.set_size_inches(12, 12)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(recordings)+1)), alarm_stats_cum_rec.loc['mean duration (sec)', :], color = 'blue')
plt.ylabel("Recordings", fontsize = 22)
plt.xlabel("seconds", fontsize = 22)
plt.title("Median duration of alarm events" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(recordings)], recordings, rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'median_duration_rec.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Create a list of all alarms occurring in any recording
total_alarm_list = set()
for recording in recordings:
total_alarm_list.update(alarm_list[recording])
total_alarm_list = sorted(total_alarm_list)
In [ ]:
# A list of all alarms occurring during the service evaluation
total_alarm_list
In [ ]:
# Write alarm list to Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'total_alarm_list.xlsx'))
DataFrame(total_alarm_list, columns = ['alarm categories']).to_excel(writer, 'total_alarm_list')
writer.save()
In [ ]:
total_alarm_number_alarms = {} # dictionary containing the number of alarm events in all recordings for the
# various alarm categories
for alarm in total_alarm_list:
total = 0
for recording in recordings:
if alarm in alarm_list[recording]:
total += len(alarm_events[recording][alarm].index)
total_alarm_number_alarms[alarm] = total
In [ ]:
# Write alarm list to Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'total_alarm_list_numbers.xlsx'))
DataFrame([total_alarm_number_alarms]).T.to_excel(writer, 'total_alarm_list')
writer.save()
In [ ]:
total_alarm_number_alarms_24H = {} # dictionary containing the number of alarm events in all recordings for the
# various alarm categories normalized for 24 hour recording periods
for alarm in total_alarm_list:
total_alarm_number_alarms_24H[alarm] = round(((total_alarm_number_alarms[alarm] /
(total_recording_time.total_seconds() / 86400))), 4)
In [ ]:
alarm_durations_alarms = {} # a dictionary of Series. Each Series contains all durations of a particular alarm
# in all recordings
for alarm in total_alarm_list:
durations = []
for recording in recordings:
if alarm in alarm_list[recording]:
durations.append(alarm_events[recording][alarm]['duration_seconds'])
durations = pd.concat(durations)
alarm_durations_alarms[alarm] = durations
In [ ]:
cum_alarm_duration_alarms = {} # dictionary containing the total duration of alarms in all recordings for the
# various alarm categories
for alarm in total_alarm_list:
cum_alarm_duration_alarms[alarm] = round(alarm_durations_alarms[alarm].sum(), 4)
In [ ]:
cum_alarm_duration_alarms_24H = {} # dictionary containing the total duration of alarms in all recordings for the
# various alarm categories normalized for 24 hour recording periods
for alarm in total_alarm_list:
cum_alarm_duration_alarms_24H[alarm] = round(((cum_alarm_duration_alarms[alarm] /
(total_recording_time.total_seconds() / 86400))), 4)
In [ ]:
# libraries containing various descriptive statistics for each recording
mean_alarm_duration_alarms = {}
median_alarm_duration_alarms = {}
sd_alarm_duration_alarms = {}
mad_alarm_duration_alarms = {}
min_alarm_duration_alarms = {}
pc25_alarm_duration_alarms = {}
pc75_alarm_duration_alarms = {}
max_alarm_duration_alarms = {}
In [ ]:
for alarm in total_alarm_list:
mean_alarm_duration_alarms[alarm] = round(alarm_durations_alarms[alarm].mean(), 4)
median_alarm_duration_alarms[alarm] = round(alarm_durations_alarms[alarm].median(), 4)
sd_alarm_duration_alarms[alarm] = round(alarm_durations_alarms[alarm].std(), 4)
mad_alarm_duration_alarms[alarm] = round(alarm_durations_alarms[alarm].mad(), 4)
min_alarm_duration_alarms[alarm] = round(alarm_durations_alarms[alarm].min(), 4)
pc25_alarm_duration_alarms[alarm] = round(alarm_durations_alarms[alarm].quantile(0.25), 4)
pc75_alarm_duration_alarms[alarm] = round(alarm_durations_alarms[alarm].quantile(0.75), 4)
max_alarm_duration_alarms[alarm] = round(alarm_durations_alarms[alarm].max(), 4)
In [ ]:
# Create DataFrame containing cumulative alarm statistics for each alarm
alarm_stats_cum_al = DataFrame([total_alarm_number_alarms,
total_alarm_number_alarms_24H,
cum_alarm_duration_alarms,
cum_alarm_duration_alarms_24H,
mean_alarm_duration_alarms,
median_alarm_duration_alarms,
sd_alarm_duration_alarms,
mad_alarm_duration_alarms,
min_alarm_duration_alarms,
pc25_alarm_duration_alarms,
pc75_alarm_duration_alarms,
max_alarm_duration_alarms],
index = ['count', 'count per 24h', 'total alarm duration (sec)', 'total alarm duration per 24 hours (sec)',
'mean duration (sec)', 'median duration (sec)', 'sd duration (sec)', 'mad duration (sec)',
'min duration (sec)', '25th cent duration (sec)', '75th cent duration (sec)',
'max duration (sec)'])
In [ ]:
# Dataframe containing cumulative alarm statistics for each alarm
alarm_stats_cum_al.round(2)
In [ ]:
# Write Dataframe containing cumulative alarm statistics for each alarm to Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'alarm_stats_cum_al.xlsx'))
alarm_stats_cum_al.round(2).to_excel(writer, 'cumulative_stats')
writer.save()
In [ ]:
# Reduce a too long alarm name
total_alarm_list[0] = 'A setting, alarm limit or vent...'
In [ ]:
# Total number of alarm events in all recordings
fig = plt.figure()
fig.set_size_inches(17, 12)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(total_alarm_list)+1)), alarm_stats_cum_al.loc['count', :], color = 'blue')
plt.ylabel("Alarms", fontsize = 22)
plt.xlabel("", fontsize = 22)
plt.title("Number of alarm events" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(total_alarm_list)], total_alarm_list, rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'number_events_al.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Total number of alarm events in all recordings normalized for 24 hour periods
fig = plt.figure()
fig.set_size_inches(17, 12)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(total_alarm_list)+1)), alarm_stats_cum_al.loc['count per 24h', :], color = 'blue')
plt.ylabel("Alarms", fontsize = 22)
plt.xlabel("", fontsize = 22)
plt.title("Number of alarm events per 24 hour" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(total_alarm_list)], total_alarm_list, rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'number_events_24H_al.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Median duration of alarm events in all recordings
fig = plt.figure()
fig.set_size_inches(17, 12)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(total_alarm_list)+1)), alarm_stats_cum_al.loc['median duration (sec)', :], color = 'blue')
plt.ylabel("Alarms", fontsize = 22)
plt.xlabel("seconds", fontsize = 22)
plt.title("Median duration of alarm events" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(total_alarm_list)], total_alarm_list, rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'median_events_al.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
all_durations = [] # Series containing durations of all alarm events in all the recording
for recording in recordings:
for alarm in alarm_list[recording]:
all_durations.append(alarm_events[recording][alarm]['duration_seconds'])
all_durations = pd.concat(all_durations)
In [ ]:
# The total number of alarm events in all the recordings
total_count = len(all_durations)
total_count
In [ ]:
# The total number of alarm events in all the recordings per 24 hour
total_count_24H = total_count / (total_recording_time.total_seconds() / 86400)
total_count_24H
In [ ]:
# Calculate descriptive statistics (expressed in seconds)
mean_duration_total = round(all_durations.mean(), 4)
median_duration_total = round(all_durations.median(), 4)
sd_duration_total = round(all_durations.std(), 4)
mad_duration_total = round(all_durations.mad(), 4)
min_duration_total = round(all_durations.min(), 4)
pc25_duration_total = round(all_durations.quantile(0.25), 4)
pc75_duration_total = round(all_durations.quantile(0.75), 4)
max_duration_total = round(all_durations.max(), 4)
In [ ]:
alarm_stats_cum_total = DataFrame([ total_count, total_count_24H,
mean_duration_total, median_duration_total,
sd_duration_total, mad_duration_total, min_duration_total,
pc25_duration_total, pc75_duration_total, max_duration_total],
columns = ['all alarms in all recordings'],
index = ['total alarm events', 'total alarm events per 24 hours',
'mean alarm duration (sec)', 'median alarm duration (sec)',
'sd alarm duration (sec)', 'mad alarm duration (sec)',
'min alarm duration (sec)', '25 centile alarm duration (sec)',
'75 centile alarm duration (sec)', 'max alarm duration (sec)'])
In [ ]:
# Cumulative statistics of the whole datasett
alarm_stats_cum_total.round(2)
In [ ]:
# Write cumulative statistics to Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'alarm_stats_cum_total.xlsx'))
alarm_stats_cum_total.to_excel(writer, 'cumulative_stats')
writer.save()
In [ ]:
# Histogram showing the number of alarms which were shorter than 1 minute
fig = plt.figure()
fig.set_size_inches(12, 6)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1)
n, bins, patches = plt.hist(all_durations, bins = range(0, 60))
plt.grid(True)
plt.xlabel('Alarm duration (seconds)', fontsize = 20)
plt.ylabel('Number of events', fontsize = 20)
plt.xticks(range(0,60,2), fontsize = 10)
plt.yticks(fontsize = 10)
plt.title('Histogram of alarm durations', fontsize = 20)
fig.savefig('%s/%s' % (DIR_WRITE, 'alarm_duration_hist_1.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Histogram showing the number of alarms which were shorter than 10 minutes
fig = plt.figure()
fig.set_size_inches(12, 6)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1)
n, bins, patches = plt.hist(all_durations, bins = range(0, 600))
plt.grid(True)
plt.xlabel('Alarm duration (seconds)', fontsize = 20)
plt.ylabel('Number of events', fontsize = 20)
plt.xticks(range(0, 600, 60), fontsize = 10)
plt.yticks(fontsize = 10)
plt.title('Histogram of alarm durations', fontsize = 20)
fig.savefig('%s/%s' % (DIR_WRITE, 'alarm_duration_hist_2.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Histogram showing all data with a bin size of 1minutes and log X axis
fig = plt.figure()
fig.set_size_inches(12, 6)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1)
n, bins, patches = plt.hist(all_durations, bins = range(0, 50000, 60))
plt.grid(True)
plt.xlabel('Alarm duration (seconds)', fontsize = 20)
plt.ylabel('Number of events', fontsize = 20)
plt.xticks(range(0, 50000, 600), fontsize = 10)
plt.yticks(fontsize = 10)
plt.xscale('log')
plt.yscale('log')
plt.title('Histogram of alarm durations', fontsize = 20)
fig.savefig('%s/%s' % (DIR_WRITE, 'alarm_duration_hist_3.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
under_10_sec = sorted([al for al in all_durations if al < 10])
len(under_10_sec)
In [ ]:
under_1_min = sorted([al for al in all_durations if al <= 60])
len(under_1_min)
In [ ]:
under_10_sec_MV_low = sorted([al for al in alarm_durations_alarms['Minute volume < low limit'] if al < 10])
under_10_sec_MV_high = sorted([al for al in alarm_durations_alarms['Minute volume > high limit'] if al < 10])
under_10_sec_RR_high = sorted([al for al in alarm_durations_alarms['Respiratory rate > high limit'] if al < 10])
In [ ]:
len(under_10_sec_MV_low), len(under_10_sec_MV_high), len(under_10_sec_RR_high)
In [ ]:
# Short alarms (<10 sec) in the categories where the user sets the limits
len(under_10_sec_MV_low) + len(under_10_sec_MV_high) + len(under_10_sec_RR_high)
In [ ]:
# How many alarm events are longer than 1 hour?
over_1_hour = sorted([al for al in all_durations if al > 3600])
len(over_1_hour)
In [ ]:
# Which alarms were longer than one hour?
alarms_over_1_hour = []
for recording in recordings:
for alarm in alarm_list[recording]:
for event in alarm_events[recording][alarm]['duration_seconds']:
if event > 3600:
alarms_over_1_hour.append((recording, alarm, event))
alarms_over_1_hour = DataFrame(sorted(alarms_over_1_hour, key = lambda x: x[2], reverse = True),
columns = ['recording', 'alarm', 'duration (seconds)'])
In [ ]:
alarms_over_1_hour
In [ ]:
alarms_over_1_hour.groupby('alarm').count()
In [ ]:
over_10_minutes = sorted([al for al in all_durations if al > 600 and al <= 3600])
len(over_10_minutes)
In [ ]:
alarms_over_10_min = []
# which alarms were longer than 10 minutes but shorter than 1 hour
for recording in recordings:
for alarm in alarm_list[recording]:
for event in alarm_events[recording][alarm]['duration_seconds']:
if event > 600 and event <= 3600:
alarms_over_10_min.append((recording, alarm, event))
In [ ]:
alarms_over_10_min = DataFrame(sorted(alarms_over_10_min, key = lambda x: x[2], reverse = True),
columns = ['recording', 'alarm', 'duration (seconds)'])
In [ ]:
alarms_over_10_min.groupby('alarm').count()
In [ ]:
over_1_minutes = sorted([al for al in all_durations if al > 60 and al <= 600])
len(over_1_minutes)
In [ ]:
alarms_over_1_min = []
# which alarms were longer than 1 minutes but shorter than 10 minutes
for recording in recordings:
for alarm in alarm_list[recording]:
for event in alarm_events[recording][alarm]['duration_seconds']:
if event > 60 and event <= 600:
alarms_over_1_min.append((recording, alarm, event))
alarms_over_1_min = DataFrame(sorted(alarms_over_1_min, key = lambda x: x[2], reverse = True),
columns = ['recording', 'alarm', 'duration (seconds)'])
In [ ]:
alarms_over_1_min.groupby('alarm').count()
In [ ]:
# Write long alarms into a multisheet Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'long_alarms.xlsx'))
alarms_over_1_hour.to_excel(writer, 'over_1hour')
alarms_over_10_min.to_excel(writer, '10min_to_1hour')
alarms_over_1_min.to_excel(writer, '1min_to_10min')
writer.save()
In [ ]:
# Identify the most frequent alarm events
frequent_alarms = alarm_stats_cum_al.loc['count'].sort_values(inplace = False, ascending = False)
In [ ]:
# The eight most frequent alarms
frequent_alarms[:8]
In [ ]:
# How many percent of all alarms were these 8 frequent alarms?
round(frequent_alarms[:8].sum() / frequent_alarms.sum(), 3) * 100
In [ ]:
# Write frequent alarm in an Excel file
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'frequent_alarms.xlsx'))
DataFrame(frequent_alarms[:8]).to_excel(writer, 'frequent_alarms')
writer.save()
In [ ]:
# Number of alarms where the user sets the limits
user_set_alarms = (frequent_alarms['Minute volume < low limit'] + frequent_alarms['Minute volume > high limit'] +
frequent_alarms['Respiratory rate > high limit'])
int(user_set_alarms)
In [ ]:
# What proportion of all alarms were these 3 user-set alarms?
print('%.3f' % (user_set_alarms / frequent_alarms.sum()))
In [ ]:
# Frequent alarms related to VT not achieved
other_frequent_alarms = (frequent_alarms['Tidal volume < low Limit'] + frequent_alarms['Volume not constant'] +
frequent_alarms['Tube obstructed'])
int(other_frequent_alarms)
In [ ]:
# What proportion of all alarms were alarms related to VT not achieved?
print('%.3f' % (other_frequent_alarms / frequent_alarms.sum()))
In [ ]:
MV_low_count = {}
for recording in recordings:
try:
MV_low_count[recording] = alarm_stats[recording]['Minute volume < low limit']['number of events'].iloc[0]
except KeyError:
# print('No "MV_low" alarm in recording %s' % recording)
pass
In [ ]:
MV_low_count_24H = {}
for recording in recordings:
try:
MV_low_count_24H[recording] = \
alarm_stats[recording]['Minute volume < low limit']['number of event per 24h'].iloc[0]
except KeyError:
# print('No "MV_low" alarm in recording %s' % recording)
pass
In [ ]:
MV_high_count = {}
for recording in recordings:
try:
MV_high_count[recording] = alarm_stats[recording]['Minute volume > high limit']['number of events'].iloc[0]
except KeyError:
# print('No "MV_high" alarm in recording %s' % recording)
pass
In [ ]:
MV_high_count_24H = {}
for recording in recordings:
try:
MV_high_count_24H[recording] = alarm_stats[recording]['Minute volume > high limit']['number of event per 24h'].iloc[0]
except KeyError:
# print('No "MV_high" alarm in recording %s' % recording)
pass
In [ ]:
RR_high_count = {}
for recording in recordings:
try:
RR_high_count[recording] = alarm_stats[recording]['Respiratory rate > high limit']['number of events'].iloc[0]
except KeyError:
# print('No "RR_high" alarm in recording %s' % recording)
pass
In [ ]:
RR_high_count_24H = {}
for recording in recordings:
try:
RR_high_count_24H[recording] = alarm_stats[recording]['Respiratory rate > high limit']['number of event per 24h'].iloc[0]
except KeyError:
# print('No "RR_high" alarm in recording %s' % recording)
pass
In [ ]:
# Plot the number of MV < low limit alarm events and write graph to file
fig = plt.figure()
fig.set_size_inches(17, 12)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(MV_low_count)+1)), MV_low_count.values(), color = 'blue')
plt.ylabel("Recordings", fontsize = 16)
plt.xlabel("number of alarm events", fontsize = 16)
plt.title("MV < low limit" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(MV_low_count.keys())], MV_low_count.keys(),
rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'MV_low.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Plot the number of MV < low limit alarm events normalized for 24 hours and write graph to file
fig = plt.figure()
fig.set_size_inches(17, 12)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(MV_low_count_24H)+1)), MV_low_count_24H.values(), color = 'blue')
plt.ylabel("Recordings", fontsize = 16)
plt.xlabel("number of alarm events per 24 hours", fontsize = 16)
plt.title("MV < low limit" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(MV_low_count_24H.keys())], MV_low_count_24H.keys(),
rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'MV_low_24H.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Plot the number of MV > low limit alarm events and write graph to file
fig = plt.figure()
fig.set_size_inches(17, 12)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(MV_high_count)+1)), MV_high_count.values(), color = 'blue')
plt.ylabel("Recordings", fontsize = 16)
plt.xlabel("number of alarm events", fontsize = 16)
plt.title("MV > high limit" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(MV_high_count.keys())], MV_high_count.keys(),
rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'MV_high.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Plot the number of MV > low limit alarm events and write graph to file
fig = plt.figure()
fig.set_size_inches(17, 12)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(MV_high_count_24H)+1)), MV_high_count_24H.values(), color = 'blue')
plt.ylabel("Recordings", fontsize = 16)
plt.xlabel("number of alarm events per 24 hours", fontsize = 16)
plt.title("MV > high limit" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(MV_high_count_24H.keys())], MV_high_count_24H.keys(),
rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'MV_high_24H.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Plot the number of RR > high limit alarm events and write graph to file
fig = plt.figure()
fig.set_size_inches(17, 12)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(RR_high_count)+1)), RR_high_count.values(), color = 'blue')
plt.ylabel("Recordings", fontsize = 16)
plt.xlabel("number of alarm events", fontsize = 16)
plt.title("RR > high limit" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(RR_high_count.keys())], RR_high_count.keys(),
rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'RR_high.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
# Plot the number of RR > high limit alarm events normalized for 24 hours and write graph to file
fig = plt.figure()
fig.set_size_inches(17, 12)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
ax1.barh(list(range(1, len(RR_high_count_24H)+1)), RR_high_count_24H.values(), color = 'blue')
plt.ylabel("Recordings", fontsize = 16)
plt.xlabel("number of alarm events per 24 hours", fontsize = 16)
plt.title("RR > high limit" , fontsize = 26)
ax1.tick_params(which = 'both', labelsize=14)
plt.yticks([i+1.5 for i, _ in enumerate(RR_high_count_24H.keys())],
RR_high_count_24H.keys(), rotation = 'horizontal')
plt.grid()
fig.savefig('%s/%s' % (DIR_WRITE, 'RR_high_24H.jpg'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
In [ ]:
for recording in recordings:
slow_measurements[recording] = pd.concat([slow_measurements[recording],
vent_settings_2[recording], alarm_settings_2[recording]], axis = 0, join = 'outer')
slow_measurements[recording].sort_index(inplace = True)
In [ ]:
for recording in recordings:
slow_measurements[recording] = slow_measurements[recording].fillna(method = 'pad')
In [ ]:
def minute_volume_plotter(rec, ylim = False):
'''
Plots the total minute volumme (using the data obtained with 1/sec sampling rate)
together with the "MV low" and "MV high" alarm limits
Displays the plot
'''
if ylim:
ymax = ylim
else:
ymax = slow_measurements[rec]['MV_high_weight'].max() + 0.3
fig = plt.figure()
fig.set_size_inches(12, 8)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
slow_measurements[rec]['MV_kg'].plot(ax = ax1, color = 'blue', ylim = [0, ymax] );
slow_measurements[rec]['MV_low_weight'].plot(ax = ax1, color = 'green', linewidth = 3, ylim = [0, ymax] );
slow_measurements[rec]['MV_high_weight'].plot(ax = ax1, color = 'red', linewidth = 3, ylim = [0, ymax] );
ax1.set_title('Minute volume - %s' % rec, size = 22, color = 'black')
ax1.set_xlabel('Time', size = 22, color = 'black')
ax1.set_ylabel('L/kg/min', size = 22, color = 'black')
ax1.grid('on', linestyle='-', linewidth=0.5, color = 'gray')
ax1.legend(['MV_kg', 'alarm_low', 'alarm_high']);
In [ ]:
minute_volume_plotter('DG003')
In [ ]:
def minute_volume_plotter_2(rec, ylim = False, version = ''):
'''
Plots the total minute volumme (using the data obtained with 1/sec sampling rate)
together with the "MV low" and "MV high" alarm limits
Writes the plot to file (does not display the plot)
'''
if ylim:
ymax = ylim
else:
ymax = slow_measurements[rec]['alarm_MV_high_weight'].max() + 0.3
fig = plt.figure()
fig.set_size_inches(12, 8)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
slow_measurements[rec]['MV_kg'].plot(ax = ax1, color = 'blue', ylim = [0, ymax] );
slow_measurements[rec]['alarm_MV_low_weight'].plot(ax = ax1, color = 'green', linewidth = 3, ylim = [0, ymax] );
slow_measurements[rec]['alarm_MV_high_weight'].plot(ax = ax1, color = 'red', linewidth = 3, ylim = [0, ymax] );
ax1.set_title('Minute volume - %s' % rec, size = 22, color = 'black')
ax1.set_xlabel('Time', size = 22, color = 'black')
ax1.set_ylabel('L/kg/min', size = 22, color = 'black')
ax1.grid('on', linestyle='-', linewidth=0.5, color = 'gray')
ax1.legend(['MV_kg', 'alarm_low', 'alarm_high']);
fig.savefig('%s/%s_%s%s.jpg' % (dir_write, 'minute_volume', rec, version), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
plt.close(fig)
In [ ]:
def resp_rate_plotter(rec, ylim = False):
'''
Plots the total reapiratory rate (using the data obtained with 1/sec sampling rate)
together with the set backup rate and "RR high" alarm limits
Displays the plot
'''
if ylim:
ymax = ylim
else:
ymax = slow_measurements[rec]['5001|RR [1/min]'].max() + 10
fig = plt.figure()
fig.set_size_inches(12, 8)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
slow_measurements[rec]['5001|RR [1/min]'].plot(ax = ax1, color = 'blue', ylim = [0, ymax] );
slow_measurements[rec]['RR_high'].plot(ax = ax1, color = 'red', linewidth = 3, ylim = [0, ymax] );
slow_measurements[rec]['RR_set'].plot(ax = ax1, color = 'green', linewidth = 3, ylim = [0, ymax] );
ax1.set_title('Respiratory rate - %s' % rec, size = 22, color = 'black')
ax1.set_xlabel('Time', size = 22, color = 'black')
ax1.set_ylabel('1/min', size = 22, color = 'black')
ax1.grid('on', linestyle='-', linewidth=0.5, color = 'gray')
ax1.legend(['RR', 'alarm_high', 'RR_set']);
In [ ]:
resp_rate_plotter('DG003')
In [ ]:
def resp_rate_plotter_2(rec, ylim = False, version = ''):
'''
Plots the total reapiratory rate (using the data obtained with 1/sec sampling rate)
together with the set backup rate and "RR high" alarm limits
Writes the plots to files (does not display the plot)
'''
if ylim:
ymax = ylim
else:
ymax = slow_measurements[rec]['5001|RR [1/min]'].max() + 10
fig = plt.figure()
fig.set_size_inches(12, 8)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
slow_measurements[rec]['5001|RR [1/min]'].plot(ax = ax1, color = 'blue', ylim = [0, ymax] );
slow_measurements[rec]['alarm_RR_high'].plot(ax = ax1, color = 'red', linewidth = 3, ylim = [0, ymax] );
slow_measurements[rec]['RR_set'].plot(ax = ax1, color = 'green', linewidth = 3, ylim = [0, ymax] );
ax1.set_title('Respiratory rate - %s' % rec, size = 22, color = 'black')
ax1.set_xlabel('Time', size = 22, color = 'black')
ax1.set_ylabel('1/min', size = 22, color = 'black')
ax1.grid('on', linestyle='-', linewidth=0.5, color = 'gray')
ax1.legend(['RR', 'alarm_high', 'RR_set'])
fig.savefig('%s/%s_%s%s.jpg' % (dir_write, 'resp_rate', rec, version), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='jpg',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)
plt.close(fig)
In [ ]:
clinical_details_for_paper = clinical_details[['Gestation', 'Birth weight', 'Current weight', 'Main diagnoses']]
clinical_details_for_paper = clinical_details_for_paper.loc[recordings]
# clinical_details_for_paper
In [ ]:
vent_modes_all = {}
for recording in recordings:
vent_modes_all[recording] = vent_modes_selected[recording].Text.unique()
vent_modes_all[recording] = [mode[5:] for mode in vent_modes_all[recording] if mode.startswith(' Mode')]
vent_modes_all = DataFrame([vent_modes_all]).T
vent_modes_all.columns = ['Ventilation modes']
vent_modes_all = vent_modes_all.loc[recordings]
# vent_modes_all
In [ ]:
recording_duration_hours_all = DataFrame([recording_duration_hours]).T
recording_duration_hours_all.columns = ['Recording duration (hours)']
In [ ]:
Table_1 = recording_duration_hours_all.join([clinical_details_for_paper, vent_modes_all])
In [ ]:
Table_1
In [ ]:
writer = pd.ExcelWriter('%s/%s' % (DIR_WRITE, 'Table_1.xlsx'))
Table_1.to_excel(writer)
writer.save()
In [ ]:
rec = 'DG032_2'
filetype = 'jpg'
dpi = 300
alarm_state = alarm_states[rec]
numbered = Series(np.zeros(len(alarm_state)), index = alarm_state.index)
for i in range(1, len(alarm_state)):
if alarm_state.iloc[i]['State New'] == 'Active':
numbered[i] = alarm_list[rec].index(alarm_state.iloc[i]['Id']) + 1
fig = plt.figure()
fig.set_size_inches(10, 4)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None, wspace=None, hspace=None)
ax1 = fig.add_subplot(1, 1, 1);
ax1.plot(alarm_state.index, numbered, '|', color = 'red', markersize = 14, markeredgewidth = 0.5 )
plt.xlabel("Time", fontsize = 14)
plt.title(rec)
plt.yticks([i+1 for i, _ in enumerate(alarm_list[rec])], alarm_list[rec], fontsize = 14);
plt.xticks(fontsize = 8)
plt.ylim(0.5, len(alarm_list[rec]) + 0.5)
fig.savefig('%s/%s.jpg' % (DIR_WRITE, 'Figure_1a'), dpi=dpi, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format= filetype,
transparent=False, bbox_inches=None, pad_inches=0.1, frameon=True)
In [ ]:
rec = 'DG032_2'
filetype = 'jpg'
dpi = 300
fig = plt.figure()
fig.set_size_inches(8, 4)
fig.subplots_adjust(left=0.5, bottom=None, right=None, top=None, wspace=None, hspace= None)
ax1 = fig.add_subplot(1, 1, 1)
xs = [i + 0.1 for i, _ in enumerate(alarm_list[rec])]
stats = []
for alarm in alarm_list[rec]:
stats.append(alarm_stats[rec][alarm]['percentage of recording length (%)'])
stats_all = pd.concat(stats)
plt.barh(xs, stats_all, color = 'red')
plt.xlabel("% of total recording time", fontsize = 14)
plt.title(rec)
plt.yticks([i + 0.5 for i, _ in enumerate(alarm_list[rec])], alarm_list[rec], fontsize = 14)
plt.xticks(fontsize = 14);
fig.savefig('%s/%s.jpg' % (DIR_WRITE, 'Figure_1b'), dpi=dpi, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format= filetype,
transparent=False, bbox_inches=None, pad_inches=0.1, frameon=True)
In [ ]:
rec = 'DG032_2'
filetype = 'tiff'
dpi = 300
alarm_state = alarm_states[rec]
numbered = Series(np.zeros(len(alarm_state)), index = alarm_state.index)
for i in range(1, len(alarm_state)):
if alarm_state.iloc[i]['State New'] == 'Active':
numbered[i] = alarm_list[rec].index(alarm_state.iloc[i]['Id']) + 1
fig = plt.figure()
fig.set_size_inches(9, 7)
fig.subplots_adjust(left=0.4, bottom=None, right=None, top=None, wspace=None, hspace=0.3)
ax1 = fig.add_subplot(2, 1, 1);
ax1.plot(alarm_state.index, numbered, '|', color = 'red', markersize = 10, markeredgewidth = 0.5 )
plt.xlabel("Time", fontsize = 12)
plt.title(rec)
plt.yticks([i+1 for i, _ in enumerate(alarm_list[rec])], alarm_list[rec], fontsize = 12);
plt.xticks(fontsize = 8)
plt.ylim(0.5, len(alarm_list[rec]) + 0.5)
ax1 = fig.add_subplot(2, 1, 2)
xs = [i + 0.1 for i, _ in enumerate(alarm_list[rec])]
stats = []
for alarm in alarm_list[rec]:
stats.append(alarm_stats[rec][alarm]['percentage of recording length (%)'])
stats_all = pd.concat(stats)
plt.barh(xs, stats_all, color = 'red')
plt.xlabel("% of total recording time", fontsize = 12)
plt.title(rec)
plt.yticks([i + 0.5 for i, _ in enumerate(alarm_list[rec])], alarm_list[rec], fontsize = 12)
plt.xticks(fontsize = 8);
fig.savefig('%s/%s.tiff' % (DIR_WRITE, 'Figure_1'), dpi=dpi, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format= filetype,
transparent=False, bbox_inches=None, pad_inches=0.1, frameon=True)
In [ ]:
rec = 'DG003'
filetype = 'jpg'
dpi = 300
ymax = slow_measurements[rec]['MV_high_weight'].max() + 0.3
fig = plt.figure()
fig.set_size_inches(8, 6)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=None)
ax1 = fig.add_subplot(1, 1, 1);
slow_measurements[rec]['MV_kg'].plot(ax = ax1, color = 'blue', ylim = [0, ymax] );
slow_measurements[rec]['MV_low_weight'].plot(ax = ax1, color = 'green', linewidth = 3, ylim = [0, ymax] );
slow_measurements[rec]['MV_high_weight'].plot(ax = ax1, color = 'red', linewidth = 3, ylim = [0, ymax] );
ax1.set_title(rec, size = 14, color = 'black')
ax1.set_xlabel('Time', size = 14, color = 'black')
ax1.set_ylabel('L/min/kg', size = 14, color = 'black')
ax1.tick_params(which = 'both', labelsize=12)
ax1.grid('on', linestyle='-', linewidth=0.5, color = 'gray')
ax1.legend(['MV_kg', 'alarm_low', 'alarm_high']);
fig.savefig('%s/%s.jpg' % (DIR_WRITE, 'Figure_2a_color'), dpi=dpi, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format= filetype,
transparent=False, bbox_inches=None, pad_inches=0.1, frameon=True)
In [ ]:
rec = 'DG003'
filetype = 'jpg'
dpi = 300
ymax = slow_measurements[rec]['MV_high_weight'].max() + 0.3
fig = plt.figure()
fig.set_size_inches(8, 6)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=None)
ax1 = fig.add_subplot(1, 1, 1);
slow_measurements[rec]['MV_kg'].plot(ax = ax1, color = 'black', alpha = 0.6, ylim = [0, ymax] );
slow_measurements[rec]['MV_low_weight'].plot(ax = ax1, color = 'black', linewidth = 3, ylim = [0, ymax] );
slow_measurements[rec]['MV_high_weight'].plot(ax = ax1, color = 'black', linewidth = 3, ylim = [0, ymax] );
ax1.set_title(rec, size = 14, color = 'black')
ax1.set_xlabel('Time', size = 14, color = 'black')
ax1.set_ylabel('L/min/kg', size = 14, color = 'black')
ax1.tick_params(which = 'both', labelsize=12)
ax1.grid('on', linestyle='-', linewidth=0.5, color = 'gray')
ax1.legend(['MV_kg', 'alarm_low', 'alarm_high']);
fig.savefig('%s/%s.jpg' % (DIR_WRITE, 'Figure_2a_bw'), dpi=dpi, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format= filetype,
transparent=False, bbox_inches=None, pad_inches=0.1, frameon=True)
In [ ]:
rec = 'DG041'
filetype = 'jpg'
dpi = 300
ymax = slow_measurements[rec]['5001|RR [1/min]'].max() + 15
fig = plt.figure()
fig.set_size_inches(8, 6)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
slow_measurements[rec]['5001|RR [1/min]'].plot(ax = ax1, color = 'blue', ylim = [0, ymax] );
slow_measurements[rec]['RR_high'].plot(ax = ax1, color = 'red', linewidth = 3, ylim = [0, ymax] );
slow_measurements[rec]['RR_set'].plot(ax = ax1, color = 'green', linewidth = 3, ylim = [0, ymax] );
ax1.set_title(rec, size = 14, color = 'black')
ax1.set_xlabel('Time', size = 14, color = 'black')
ax1.set_ylabel('1/min', size = 14, color = 'black')
ax1.grid('on', linestyle='-', linewidth=0.5, color = 'gray')
ax1.legend(['RR', 'alarm_high', 'RR_set'])
fig.savefig('%s/%s.jpg' % (DIR_WRITE, 'Figure_2b_color'), dpi=dpi, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format= filetype,
transparent=False, bbox_inches=None, pad_inches=0.1, frameon=True)
In [ ]:
rec = 'DG041'
filetype = 'jpg'
dpi = 300
ymax = slow_measurements[rec]['5001|RR [1/min]'].max() + 15
fig = plt.figure()
fig.set_size_inches(8, 6)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=0.7)
ax1 = fig.add_subplot(1, 1, 1);
slow_measurements[rec]['5001|RR [1/min]'].plot(ax = ax1, color = 'black', alpha = 0.6, ylim = [0, ymax] );
slow_measurements[rec]['RR_high'].plot(ax = ax1, color = 'black', linewidth = 3, ylim = [0, ymax] );
slow_measurements[rec]['RR_set'].plot(ax = ax1, color = 'black', linewidth = 3, ylim = [0, ymax] );
ax1.set_title(rec, size = 14, color = 'black')
ax1.set_xlabel('Time', size = 14, color = 'black')
ax1.set_ylabel('1/min', size = 14, color = 'black')
ax1.grid('on', linestyle='-', linewidth=0.5, color = 'gray')
ax1.legend(['RR', 'alarm_high', 'RR_set'])
fig.savefig('%s/%s.jpg' % (DIR_WRITE, 'Figure_2b_bw'), dpi=dpi, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format= filetype,
transparent=False, bbox_inches=None, pad_inches=0.1, frameon=True)
In [ ]:
rec0 = 'DG003'
rec1 = 'DG041'
filetype = 'tiff'
dpi = 300
ymax0 = slow_measurements[rec0]['MV_high_weight'].max() + 0.3
ymax1 = slow_measurements[rec1]['5001|RR [1/min]'].max() + 15
fig = plt.figure()
fig.set_size_inches(6, 9)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.3)
ax0 = fig.add_subplot(2, 1, 1);
slow_measurements[rec0]['MV_kg'].plot(ax = ax0, color = 'blue', ylim = [0, ymax0] );
slow_measurements[rec0]['MV_low_weight'].plot(ax = ax0, color = 'green', linewidth = 3, ylim = [0, ymax0] );
slow_measurements[rec0]['MV_high_weight'].plot(ax = ax0, color = 'red', linewidth = 3, ylim = [0, ymax0] );
ax0.set_title(rec0, size = 12, color = 'black')
ax0.set_xlabel('', size = 12, color = 'black')
ax0.set_ylabel('L/min/kg', size = 12, color = 'black')
ax0.tick_params(which = 'both', labelsize=10)
ax0.grid('on', linestyle='-', linewidth=0.5, color = 'gray')
ax0.legend(['MV_kg', 'alarm_low', 'alarm_high']);
ax1 = fig.add_subplot(2, 1, 2);
slow_measurements[rec1]['5001|RR [1/min]'].plot(ax = ax1, color = 'blue', ylim = [0, ymax1] );
slow_measurements[rec1]['RR_high'].plot(ax = ax1, color = 'red', linewidth = 3, ylim = [0, ymax1] );
slow_measurements[rec1]['RR_set'].plot(ax = ax1, color = 'green', linewidth = 3, ylim = [0, ymax1] );
ax1.set_title(rec1, size = 12, color = 'black')
ax1.set_xlabel('Time', size = 12, color = 'black')
ax1.set_ylabel('1/min', size = 12, color = 'black')
ax1.tick_params(which = 'both', labelsize=10)
ax1.grid('on', linestyle='-', linewidth=0.5, color = 'gray')
ax1.legend(['RR', 'alarm_high', 'RR_set'], loc = 4)
fig.savefig('%s/%s.tiff' % (DIR_WRITE, 'Figure_2'), dpi=dpi, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format= filetype,
transparent=False, bbox_inches=None, pad_inches=0.1, frameon=True)
In [ ]:
# Histogram showing the number of alarms which were shorter than 1 minute
fig = plt.figure()
fig.set_size_inches(7, 5)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
ax1 = fig.add_subplot(1, 1, 1)
n, bins, patches = plt.hist(all_durations, bins = range(0, 60))
plt.grid(True)
plt.xlabel('Alarm duration (seconds)', fontsize = 12)
plt.ylabel('Number of alarm events', fontsize = 12)
plt.xticks(range(0,60,4), fontsize = 12)
plt.yticks(fontsize = 12)
plt.title('Histogram of alarm durations', fontsize = 12)
fig.savefig('%s/%s' % (DIR_WRITE, 'Figure_3.tiff'), dpi=300, facecolor='w', edgecolor='w',
orientation='portrait', papertype=None, format='tiff',
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=True)