예제 #1
0
def load_existing_ekgAnnotations(startTime, endTime, ekgNote):
    """Loads existing annotations from file.

    Parameters -- from column file headers
    ----------
    startTime:str
        Timestamp marking beginning of annotation, preferably in ISO format.

    endTime:str
        Timestamp marking end of annotation, preferably in ISO format.

    ekgNote:str
        Annotation code for EKG (e.g. "EKG Interpretable")

    Returns
    -------

    """

    ekgIdx = annotatorSettings.ekgCodes.index(ekgNote)

    ekgComments = BoxAnnotation(
        fill_color=annotatorSettings.ekgColorSelector[ekgIdx])
    views.ekgViewer.add_layout(ekgComments)

    # FIXME: Timestamp issue likely in the future.
    # I honestly do not know why these values work...but there is a current issue with Bokeh datetime.
    # I subtracted the timestamp provided by x1 and the known epoch UTC timestamp of 1/1/2020 to get 18000000000000.
    # I divided by various magnitudes of 10 until timestamp on bokeh was correct.
    ekgComments.left = pd.to_datetime(str(startTime)).tz_localize('Etc/GMT+4')
    ekgComments.right = pd.to_datetime(str(endTime)).tz_localize('Etc/GMT+4')
예제 #2
0
def load_existing_ekgAnnotations(startTime, endTime, ekgNote):
    """Loads existing annotations from file.

    Parameters -- from column file headers
    ----------
    startTime:str
        Timestamp marking beginning of annotation, preferably in ISO format.

    endTime:str
        Timestamp marking end of annotation, preferably in ISO format.

    ekgNote:str
        Annotation code for EKG (e.g. "EKG Interpretable")

    Returns
    -------

    """

    global ekgColorSelector

    ekgIdx = annotatorSettings.ekgCodes.index(ekgNote)

    ekgComments = BoxAnnotation(fill_color=ekgColorSelector[ekgIdx])
    ekgViewer.add_layout(ekgComments)

    # FIXME: Timestamp issue likely in the future.
    # I honestly do not know why these values work...but there is a current issue with Bokeh datetime.
    # I subtracted the timestamp provided by x1 and the known epoch UTC timestamp of 1/1/2020 to get 18000000000000.
    # I divided by various magnitudes of 10 until timestamp on bokeh was correct.
    ekgComments.left = pd.to_datetime(str(startTime)).tz_localize('Etc/GMT+4')
    ekgComments.right = pd.to_datetime(str(endTime)).tz_localize('Etc/GMT+4')
예제 #3
0
def load_existing_ppgQos_annotations(startTime, endTime, ppgNote, qosNote):
    """Loads existing annotations from file.

    Parameters -- from file column headers
    ----------
    startTime:str
        Timestamp marking beginning of annotation, preferably in ISO format.

    endTime:str
        Timestamp marking end of annotation, preferably in ISO format.

    ppgNote:str
        Annotation code for PPG (e.g. "PPG Interpretable")

    qosNote:str
        Annotation code for QoS (e.g. "QoS Correct")

    Returns
    -------

    """

    global ppgColorSelector, ppgViewer

    ppgIdx = annotatorSettings.ppgCodes.index(ppgNote)
    qosIdx = annotatorSettings.qosCodes.index(qosNote)

    # Use ppgNote and qosNote to determine color of loaded annotation to add to plot.
    ppgComments = BoxAnnotation(fill_color=ppgColorSelector[ppgIdx])
    ppgViewer.add_layout(ppgComments)

    # FIXME: Timestamp issue likely in the future.
    # I honestly do not know why these values work...but there is a current issue with Bokeh datetime.
    # I subtracted the timestamp provided by x1 and the known epoch UTC timestamp of 1/1/2020 to get 18000000000000.
    # I divided by various magnitudes of 10 until timestamp on bokeh was correct.
    ppgComments.left = (pd.to_datetime(str(startTime)).value +
                        18000000000000) / 1000000
    ppgComments.right = (pd.to_datetime(str(endTime)).value +
                         18000000000000) / 1000000

    qosComments = BoxAnnotation(fill_color=qosColorSelector[qosIdx],
                                fill_alpha=1)
    ppgViewer.add_layout(qosComments)
    qosComments.top = annotatorSettings.ppgYRange[1]
    qosComments.bottom = annotatorSettings.ppgYRange[1] - 100

    qosComments.left = (pd.to_datetime(str(startTime)).value +
                        18000000000000) / 1000000
    qosComments.right = (pd.to_datetime(str(endTime)).value +
                         18000000000000) / 1000000
예제 #4
0
def ppgViewerSelectionCallback(attr, old, new):
    """Create an annotation based on the geometry of the box select tool.

    Parameters
    ----------
    attr:str
        'geometries'

    old:list
        e.g. [{'vx0': 464, 'vy0': 23.7869873046875, 'y0': 0, 'y1': 4503.400000000001, 'type': 'rect', 'x0': 1481149362095.9377, 'vx1': 552, 'x1': 1481149364565.3564, 'vy1': 341.03603515625}]

    new:list
        e.g. [{'vx0': 464, 'vy0': 23.7869873046875, 'y0': 0, 'y1': 4503.400000000001, 'type': 'rect', 'x0': 1481149362095.9377, 'vx1': 552, 'x1': 1481149364565.3564, 'vy1': 341.03603515625}]


    Returns
    -------

    """

    # Provide globals to help reader know what is local and global
    global ppgViewer, ppgDataFrame, args, ppgColorSelector, qosColorSelector, ppgButtonGroup, qosButtonGroup

    # Edge case. Make sure minimum x value for annotation is 0.
    if new[0]['x0'] < 0:
        x0 = 0
    else:
        x0 = abs(int(new[0]['x0']))

    x1 = abs(int(new[0]['x1']))

    # Create box annotation. Color of annotation depends on which button in a group is selected (active).
    ppgComments = BoxAnnotation(
        fill_color=ppgColorSelector[ppgButtonGroup.active])
    ppgViewer.add_layout(ppgComments)

    ppgComments.left = x0
    ppgComments.right = x1

    # Create box annotation. Color of annotation depends on which button in a group is selected (active).
    qosComments = BoxAnnotation(
        fill_color=qosColorSelector[qosButtonGroup.active], fill_alpha=1)
    ppgViewer.add_layout(qosComments)

    qosComments.top = annotatorSettings.ppgYRange[1]
    qosComments.bottom = annotatorSettings.ppgYRange[1] - 100
    qosComments.left = x0
    qosComments.right = x1

    save_annotation_dimensions(x0, x1, args.spo2QosAnnotatedFile)
예제 #5
0
def ppgViewerSelectionCallback(attr, old, new):
    """Create an annotation based on the geometry of the box select tool.

    Parameters
    ----------
    attr:str
        'geometries'

    old:list
        e.g. [{'vx0': 464, 'vy0': 23.7869873046875, 'y0': 0, 'y1': 4503.400000000001, 'type': 'rect', 'x0': 1481149362095.9377, 'vx1': 552, 'x1': 1481149364565.3564, 'vy1': 341.03603515625}]

    new:list
        e.g. [{'vx0': 464, 'vy0': 23.7869873046875, 'y0': 0, 'y1': 4503.400000000001, 'type': 'rect', 'x0': 1481149362095.9377, 'vx1': 552, 'x1': 1481149364565.3564, 'vy1': 341.03603515625}]


    Returns
    -------

    """

    # Provide globals to help reader know what is local and global
    global ppgViewer, ppgDataFrame, args, ppgColorSelector, qosColorSelector, ppgButtonGroup, qosButtonGroup


    # Edge case. Make sure minimum x value for annotation is 0.
    if new[0]['x0'] < 0:
        x0 = 0
    else:
        x0 = abs(int(new[0]['x0']))

    x1 = abs(int(new[0]['x1']))

    # Create box annotation. Color of annotation depends on which button in a group is selected (active).
    ppgComments = BoxAnnotation(fill_color=ppgColorSelector[ppgButtonGroup.active])
    ppgViewer.add_layout(ppgComments)

    ppgComments.left = x0
    ppgComments.right = x1

    # # Create box annotation. Color of annotation depends on which button in a group is selected (active).
    # qosComments = BoxAnnotation(fill_color=qosColorSelector[qosButtonGroup.active], fill_alpha=1)
    # ppgViewer.add_layout(qosComments)
    #
    # qosComments.top = annotatorSettings.ppgYRange[1]
    # qosComments.bottom = annotatorSettings.ppgYRange[1] - 100
    # qosComments.left = x0
    # qosComments.right = x1

    save_annotation_dimensions(x0,x1,args.spo2QosAnnotatedFile)
예제 #6
0
def ekgViewerSelectionCallback(attr, old, new):
    """Create an annotation based on the geometry of the box select tool.

    Parameters
    ----------
    attr:str
        'geometries'

    old:list
        e.g. [{'vx0': 464, 'vy0': 23.7869873046875, 'y0': 0, 'y1': 4503.400000000001, 'type': 'rect', 'x0': 1481149362095.9377, 'vx1': 552, 'x1': 1481149364565.3564, 'vy1': 341.03603515625}]

    new:list
        e.g. [{'vx0': 464, 'vy0': 23.7869873046875, 'y0': 0, 'y1': 4503.400000000001, 'type': 'rect', 'x0': 1481149362095.9377, 'vx1': 552, 'x1': 1481149364565.3564, 'vy1': 341.03603515625}]


    Returns
    -------

    """

    # Provide globals to help reader know what is local and global
    global ekgViewer, args, ekgColorSelector, ekgButtonGroup

    # Edge case. Make sure minimum x value for annotation is 0.
    if new[0]['x0'] < 0:
        x0 = 0
    else:
        x0 = abs(int(new[0]['x0']))

    x1 = abs(int(new[0]['x1']))

    # Create box annotation. Color of annotation depends on which button in a group is selected (active).
    ekgComments = BoxAnnotation(
        fill_color=ekgColorSelector[ekgButtonGroup.active])
    ekgComments.left = x0
    ekgComments.right = x1
    ekgViewer.add_layout(ekgComments)

    save_annotation_dimensions(x0, x1, args.ekgAnnotatedFile)
예제 #7
0
def ekgViewerSelectionCallback(attr, old, new):
    """Create an annotation based on the geometry of the box select tool.

    Parameters
    ----------
    attr:str
        'geometries'

    old:list
        e.g. [{'vx0': 464, 'vy0': 23.7869873046875, 'y0': 0, 'y1': 4503.400000000001, 'type': 'rect', 'x0': 1481149362095.9377, 'vx1': 552, 'x1': 1481149364565.3564, 'vy1': 341.03603515625}]

    new:list
        e.g. [{'vx0': 464, 'vy0': 23.7869873046875, 'y0': 0, 'y1': 4503.400000000001, 'type': 'rect', 'x0': 1481149362095.9377, 'vx1': 552, 'x1': 1481149364565.3564, 'vy1': 341.03603515625}]


    Returns
    -------

    """

    # Provide globals to help reader know what is local and global
    global ekgViewer, args, ekgColorSelector, ekgButtonGroup

    # Edge case. Make sure minimum x value for annotation is 0.
    if new[0]['x0'] < 0:
        x0 = 0
    else:
        x0 = abs(int(new[0]['x0']))

    x1 = abs(int(new[0]['x1']))

    # Create box annotation. Color of annotation depends on which button in a group is selected (active).
    ekgComments = BoxAnnotation(fill_color=ekgColorSelector[ekgButtonGroup.active])
    ekgComments.left = x0
    ekgComments.right = x1
    ekgViewer.add_layout(ekgComments)

    save_annotation_dimensions(x0,x1,args.ekgAnnotatedFile)
예제 #8
0
def load_existing_ppgQos_annotations(startTime, endTime, ppgNote, qosNote):
    """Loads existing annotations from file.

    Parameters -- from file column headers
    ----------
    startTime:str
        Timestamp marking beginning of annotation, preferably in ISO format.

    endTime:str
        Timestamp marking end of annotation, preferably in ISO format.

    ppgNote:str
        Annotation code for PPG (e.g. "PPG Interpretable")

    qosNote:str
        Annotation code for QoS (e.g. "QoS Correct")

    Returns
    -------

    """

    global ppgColorSelector, ppgViewer

    if ppgNote != '':
        ppgIdx = annotatorSettings.ppgCodes.index(ppgNote)

        # Use ppgNote and qosNote to determine color of loaded annotation to add to plot.
        ppgComments = BoxAnnotation(fill_color=ppgColorSelector[ppgIdx])
        ppgViewer.add_layout(ppgComments)

        # FIXME: Timestamp issue likely in the future.
        # I honestly do not know why these values work...but there is a current issue with Bokeh datetime.
        # I subtracted the timestamp provided by x1 and the known epoch UTC timestamp of 1/1/2020 to get 18000000000000.
        # I divided by various magnitudes of 10 until timestamp on bokeh was correct.
        ppgComments.left = pd.to_datetime(str(startTime)).tz_localize('Etc/GMT+4')
        ppgComments.right = pd.to_datetime(str(endTime)).tz_localize('Etc/GMT+4')

    if qosNote != '':
        qosIdx = annotatorSettings.qosCodes.index(qosNote)
        qosComments = BoxAnnotation(fill_color=qosColorSelector[qosIdx],fill_alpha=0.5)
        ppgViewer2.add_layout(qosComments)
        # qosComments.top = annotatorSettings.ppgYRange[1]
        # qosComments.bottom = annotatorSettings.ppgYRange[1] - 100

        qosComments.left = pd.to_datetime(str(startTime)).tz_localize('Etc/GMT+4')
        qosComments.right = pd.to_datetime(str(endTime)).tz_localize('Etc/GMT+4')
예제 #9
0
def add_anno():
    alarm = alarms.alarms[alarmNumber]
    ala = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                        fill_alpha=0.5)
    ala2 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                         fill_alpha=0.5)
    ala3 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                         fill_alpha=0.5)
    ala5 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                         fill_alpha=0.5)
    ala6 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                         fill_alpha=0.5)
    ala7 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                         fill_alpha=0.5)

    views.ekgViewer.add_layout(ala)
    views.ppgViewer.add_layout(ala2)
    views.hrViewer.add_layout(ala3)
    views.bpViewer.add_layout(ala5)
    views.spo2Viewer.add_layout(ala6)
    views.ppgViewer2.add_layout(ala7)

    ala.left = pd.to_datetime(str(alarm)) - pd.Timedelta('0.25 seconds')
    ala.right = pd.to_datetime(str(alarm)) + pd.Timedelta('0.25 seconds')
    ala2.left = pd.to_datetime(str(alarm)) - pd.Timedelta('0.25 seconds')
    ala2.right = pd.to_datetime(str(alarm)) + pd.Timedelta('0.25 seconds')
    ala3.left = pd.to_datetime(str(alarm)) - pd.Timedelta('0.25 seconds')
    ala3.right = pd.to_datetime(str(alarm)) + pd.Timedelta('0.25 seconds')
    ala5.left = pd.to_datetime(str(alarm)) - pd.Timedelta('0.25 seconds')
    ala5.right = pd.to_datetime(str(alarm)) + pd.Timedelta('0.25 seconds')
    ala6.left = pd.to_datetime(str(alarm)) - pd.Timedelta('0.25 seconds')
    ala6.right = pd.to_datetime(str(alarm)) + pd.Timedelta('0.25 seconds')
    ala7.left = pd.to_datetime(str(alarm)) - pd.Timedelta('0.25 seconds')
    ala7.right = pd.to_datetime(str(alarm)) + pd.Timedelta('0.25 seconds')
예제 #10
0
# Availability: https://github.com/bokeh/bokeh  #
#################################################

from bokeh.core.properties import Bool, List, Instance, String, Enum, Int
from bokeh.models.annotations import Label
from bokeh.models.tools import Drag, BoxAnnotation
from bokeh.models.renderers import Renderer
from bokeh.models.callbacks import Callback
from bokeh.core.enums import Dimensions

_DEFAULT_BOX_ANNOTATION = lambda: BoxAnnotation(level="overlay",
                                                render_mode="css",
                                                top_units="screen",
                                                left_units="screen",
                                                bottom_units="screen",
                                                right_units="screen",
                                                fill_color="#ff3333",
                                                fill_alpha=0.3,
                                                line_color="red",
                                                line_alpha=1.0,
                                                line_width=2,
                                                line_dash=[4, 4])


class MeasureJTool(Drag):

    __implementation__ = "measureJTool.ts"

    names = List(String)

    renderers = List(Instance(Renderer))
예제 #11
0

with open(spo2QosAnnotatedFile, 'r') as readfile:
    reader = csv.reader(readfile)
    next(reader)
    for row in reader:
        load_existing_ppgQos_annotations(row[0], row[1], row[2], row[3])

with open(ekgAnnotatedFile, 'r') as readfile:
    reader = csv.reader(readfile)
    next(reader)
    for row in reader:
        load_existing_ekgAnnotations(row[0], row[1], row[2])

for alarm in alarms:
    ala = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                        fill_alpha=0.5)
    ala2 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                         fill_alpha=0.5)
    ala3 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                         fill_alpha=0.5)
    ala4 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                         fill_alpha=0.5)
    ala5 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                         fill_alpha=0.5)
    ala6 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,
                         fill_alpha=0.5)

    ekgViewer.add_layout(ala)
    ppgViewer.add_layout(ala2)
    hrViewer.add_layout(ala3)
    ekgViewer.add_layout(ala4)
예제 #12
0
with open(spo2QosAnnotatedFile,'r') as readfile:
    reader = csv.reader(readfile)
    next(reader)
    for row in reader:
        load_existing_ppgQos_annotations(row[0], row[1], row[2], row[3])

with open(ekgAnnotatedFile,'r') as readfile:
    reader = csv.reader(readfile)
    next(reader)
    for row in reader:
        load_existing_ekgAnnotations(row[0], row[1], row[2])


for alarm in alarms:
    ala = BoxAnnotation(fill_color=annotatorSettings.alarmColor,fill_alpha=0.5)
    ala2 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,fill_alpha=0.5)
    ala3 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,fill_alpha=0.5)
    ala4 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,fill_alpha=0.5)
    ala5 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,fill_alpha=0.5)
    ala6 = BoxAnnotation(fill_color=annotatorSettings.alarmColor,fill_alpha=0.5)


    ekgViewer.add_layout(ala)
    ppgViewer.add_layout(ala2)
    hrViewer.add_layout(ala3)
    ekgViewer.add_layout(ala4)
    bpViewer.add_layout(ala5)
    spo2Viewer.add_layout(ala6)

    ala.left = pd.to_datetime(str(alarm))-pd.Timedelta('0.25 seconds')