In [1]:
from IPython.display import Audio
sound_file = 'beep-05.wav'

In [2]:
# Import Modules and Identify Low Signals
import numpy as np
import pandas as pd
from datetime import datetime, timedelta
from pandas import Series, DataFrame, concat
import ROPtimes as rt



#Define any string with 'C' as NaN. 'C' is an indicator for the Masimo as a low signal reading
def readD(val):
    if 'C' in val:
        return np.nan
    return val

%matplotlib inline

In [3]:
Baby_lst = ['ROP003', 'ROP005', 'ROP006', 'ROP007', 'ROP008', 'ROP009', 'ROP010',
          'ROP011', 'ROP012', 'ROP013', 'ROP014', 'ROP015', 'ROP017', 'ROP018',
          'ROP019', 'ROP020', 'ROP021', 'ROP022', 'ROP023', 'ROP025']

#update this as you go

In [4]:
fdf = []

for Baby in Baby_lst:
    
    #### Load Dict of ROP times
    BabyDict = getattr(rt, Baby) 
    
    #### Load Files
    
    dfNIRSpre0 = pd.read_csv('/Users/John/Dropbox/LLU/Projects/Retinopathy of Prematurity/NIRS/Clean/' + Baby + 'NIRS.csv',
                             parse_dates={'timestamp': ['Date',' Time']},
                             index_col='timestamp',
                             usecols=['Date', ' Time', ' Ch2 %StO2'],
                             na_values=['0'])

    dfPOpre0 = pd.read_csv('/Users/John/Dropbox/LLU/Projects/Retinopathy of Prematurity/Pulse Ox/' + Baby + 'PO.csv',
                           parse_dates={'timestamp': ['Date','Time']},
                           index_col='timestamp',
                           usecols=['Date', 'Time', 'SpO2', 'PR'],
                           na_values=['0'])

    dfPIpre0 = pd.read_csv('/Users/John/Dropbox/LLU/Projects/Retinopathy of Prematurity/Pulse Ox/' + Baby + 'PO.csv',
                           parse_dates={'timestamp': ['Date','Time']},
                               #Parse_dates tells the read_csv function to combine the date and time column
                           index_col='timestamp',
                           usecols=['Date', 'Time', 'PI', 'Exceptions'],
                           na_values=['0'], #Na_values is used to turn 0 into NaN
                           converters={'Exceptions':  readD}
                               #Converters: readD is the dict that means any string with 'C' with be NaN (for PI)
                           ) 

    dfNIRSpre = dfNIRSpre0.rename(columns={' Ch2 %StO2': 'StO2'}) #rename NIRS column

    ### Clean the PI dataframe to get rid of rows that have NaN
    dfPIpre = dfPIpre0.dropna(how='any')

    
    ### Combine PI dataframe with the rest of the Pulse Ox dataframe after cleaning
    dfPOpre = dfPIpre.combine_first(dfPOpre0)
    
    #
    
    # Phone almost always equals Philips monitor

    # NIRS date/time is 2 mins and 10 seconds slower than phone. Have to correct for it.
    # Pulse ox date/time is 1 mins and 32 seconds faster than phone. Have to correct for it.

    #This code is to make the combined dataframe come in even seconds.
    #The corrected is 1 second, + for NIRS and - for PO.

    #
    ###time correction
    #
    
    
    TCcorrect = timedelta(seconds=1)

    ncorr = dfNIRSpre.index+TCcorrect
    pcorr = dfPOpre.index-TCcorrect


    if dfNIRSpre.index[:1].second % 2 == 0:
        if dfPOpre.index[:1].second % 2 == 0:
            print '%s Both NIRS and PO indices are even.' % Baby
        elif dfPOpre.index[:1].second % 2 != 0:
            print '%s NIRS even, PO odd. PO index corrected.' % Baby
            dfPOpre = dfPOpre.set_index(pcorr)
        else:
            raise NameError('Indices are messed up')
    elif dfNIRSpre.index[:1].second % 2 != 0:
        if dfPOpre.index[:1].second % 2 == 0:
            print '%s nNIRS odd, PO even. NIRS index corrected.' % Baby
            dfNIRSpre = dfNIRSpre.set_index(ncorr)
        elif dfPOpre.index[:1].second % 2 != 0:
            print '%s Both NIRS and PO indices are odd. Both corrected' % Baby
            dfNIRSpre = dfNIRSpre.set_index(ncorr)
            dfPOpre = dfPOpre.set_index(pcorr)
    else:
        raise NameError('%s Indices are messed up') % Baby

    TCnirs = timedelta(minutes=2, seconds=10)
    TCpo = timedelta(minutes=1, seconds=32)
    # NIRS is slower than correct time, need to add TCnirs to catch it up
    # PO is faster than correct time, need to subtract TCpo to slow it down

    dfNIRS = dfNIRSpre.set_index([dfNIRSpre.index+TCnirs]) #NIRS Time Correction
    dfPO = dfPOpre.set_index([dfPOpre.index-TCpo]) #PO Time Correction
    #for babies that only had one machine

    dffakePO = pd.DataFrame({'SpO2':np.NaN, 'PR':np.NaN, 'PI':np.NaN}, index=dfNIRS.index)
    dffakeNIRS = pd.DataFrame({'StO2':np.NaN}, index=dfPO.index)

    if len(dfNIRS) > 5:
        if len(dfPO) > 5:
            df = dfNIRS.combine_first(dfPO) #Combine two DataFrame objects and default to non-null values in frame
            Masimo = True
            NIRS = True
            print '%s Both machines on' % Baby
        elif len(dfPO) < 5:
            df = dfNIRS.combine_first(dffakePO)
            print '%s Only NIRS on' % Baby
            NIRS = True
            Masimo = False
    elif len(dfNIRS) < 5:
        df = dffakeNIRS.combine_first(dfPO)
        Masimo = True
        NIRS = False
        print '%s Only Masimo on' % Baby
    else:
        raise NameError('Check your files')
        
    
    # add FTOE
    dfpreFTOE = pd.DataFrame({'SpO2' : df['SpO2'].values, 'StO2' : df['StO2'].values}, index=df.index)

    psa = dfpreFTOE['SpO2']
    prs = dfpreFTOE['StO2']

    # FTOE = (SpO2 –StO2) / SpO2 * 100
    dfFTOE = pd.DataFrame({'FTOE' : (((psa-prs)/psa)*100)})

    df = df.join(dfFTOE)
    
    # add ID label. Only include tens and ones place
    df['ID'] = Series((Baby[4:]), index=df.index)
    
    #remove 0's to NaNs
    df.replace(0, np.nan)
    
    #NaN to blank for SAS
    df = df.fillna('')
    
    #drop exceptions
    if Masimo != False:
        df = df.drop('Exceptions', 1)
    
    #change it to relative time
    dfind = (df.index-BabyDict['ExamStart']).total_seconds()
    df = df.set_index(dfind)
    
    #rearrange columns
    df = df[['ID', 'PI', 'PR', 'SpO2', 'StO2', 'FTOE']]
    
    # combine dfs
    fdf.append(df)
    dff = pd.concat(fdf, axis=0)
    
Audio(url=sound_file, autoplay=True)


ROP003 Both NIRS and PO indices are odd. Both corrected
ROP003 Only NIRS on
ROP005 NIRS even, PO odd. PO index corrected.
ROP005 Only NIRS on
ROP006 Both NIRS and PO indices are odd. Both corrected
ROP006 Only Masimo on
ROP007 NIRS even, PO odd. PO index corrected.
ROP007 Both machines on
ROP008 Both NIRS and PO indices are odd. Both corrected
ROP008 Both machines on
ROP009 nNIRS odd, PO even. NIRS index corrected.
ROP009 Both machines on
ROP010 Both NIRS and PO indices are even.
ROP010 Only Masimo on
ROP011 NIRS even, PO odd. PO index corrected.
ROP011 Both machines on
ROP012 NIRS even, PO odd. PO index corrected.
ROP012 Both machines on
ROP013 nNIRS odd, PO even. NIRS index corrected.
ROP013 Both machines on
ROP014 Both NIRS and PO indices are odd. Both corrected
ROP014 Both machines on
ROP015 Both NIRS and PO indices are even.
ROP015 Both machines on
ROP017 Both NIRS and PO indices are even.
ROP017 Both machines on
ROP018 nNIRS odd, PO even. NIRS index corrected.
ROP018 Both machines on
ROP019 NIRS even, PO odd. PO index corrected.
ROP019 Both machines on
ROP020 Both NIRS and PO indices are even.
ROP020 Both machines on
ROP021 NIRS even, PO odd. PO index corrected.
ROP021 Both machines on
ROP022 nNIRS odd, PO even. NIRS index corrected.
ROP022 Both machines on
ROP023 NIRS even, PO odd. PO index corrected.
ROP023 Both machines on
ROP025 NIRS even, PO odd. PO index corrected.
ROP025 Both machines on
Out[4]:

In [5]:
dff.to_csv('ROPraw_clean.csv')

In [15]:
#get list of ROP ID first eyedrop times

for Baby in Baby_lst:
    
    #### Load Dict of ROP times
    BabyDict = getattr(rt, Baby)
    
    eyedroptime = (BabyDict['EyeDrop1']-BabyDict['ExamStart']).total_seconds()
    
    print Baby, eyedroptime


ROP003 -7320.0
ROP005 -7920.0
ROP006 -5160.0
ROP007 -4740.0
ROP008 -5460.0
ROP009 -3120.0
ROP010 -2940.0
ROP011 -3360.0
ROP012 -5100.0
ROP013 -3960.0
ROP014 -4740.0
ROP015 -3120.0
ROP017 -6180.0
ROP018 -5040.0
ROP019 -3180.0
ROP020 -6120.0
ROP021 -6300.0
ROP022 -6360.0
ROP023 -4620.0
ROP025 -8520.0

In [ ]: