In [1]:
import psycopg2
from psycopg2.extensions import register_adapter, AsIs
import matplotlib.pyplot as plt
import collections
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from sklearn.cluster import KMeans
import string
import wfdb

np.set_printoptions(suppress=True,precision=10)

In [2]:
def obtainMeasures(dbname="mimic",unlimit=False,centroid=None) :
    conn = psycopg2.connect("dbname="+dbname)
    cur = conn.cursor()
    limit = "" if unlimit else " LIMIT 10000 "
    null = " AND centroid is null" if centroid is None else "AND centroid IS NOT NULL" if centroid =="notNull" else "" 
    select_stament = ("SELECT DISTINCT qt,ts,sr,centroid FROM rstq "
                      " WHERE qt IS NOT NULL "
                      " AND qt > 0 and qt<1000 "
                      " AND ts IS NOT NULL "
                      " AND sr IS NOT NULL "+null+limit)
    cur.execute(select_stament)
    waves = []
    for row in cur :
        qt = row[0]
        ts = row[1]
        sr = row[2]
        if centroid  =="notNull" :
            waves.append([qt,ts,sr,row[3]])
        else :
            waves.append([qt,ts,sr])
    conn.close()
    return waves

In [3]:
fig_size = [12,9]
plt.rcParams["figure.figsize"] = fig_size
def printKmeans(kmeans) :
    labels, values = zip(*collections.Counter(kmeans.labels_).items())
    indexes = np.arange(len(labels))
    width = 0.5
    fig, ax = plt.subplots() 
    for i, v in enumerate(values):
        ax.text(i-0.1,v+1, str(v), color='blue', fontweight='bold')
    plt.bar(indexes, values, width)
    plt.title('Cantidad de Latidos por centroide')
    plt.ylabel('Cantidad de latidos')
    plt.xlabel('Centroides')
    plt.xticks(indexes + width * 0.01, labels)
    plt.show()

In [4]:
waves = obtainMeasures(centroid="all",unlimit=True)
X = np.array(waves)

In [5]:
centroid=np.array([
    [61.8053426046,32.2787555518,23.118412623]
    ,[21.6078916954,72.8152963513,31.9357045567]
    ,[144.8370126103,32.3604470092,14.1864370554]
    ,[271.6645211372,31.0926998092,14.8024064431]
    ,[445.1792934903,28.9046878471,15.2207657558]
    ,[25.8738705513,83.0490503411,350.6367324359]
    ,[725.530715005,25.9460221551,13.7321248741]
    ,[21.620352867,416.3456206679,98.9187145558]])
kmeans = KMeans(n_clusters=8
                ,init=centroid,n_init=1
               ).fit(X)

In [6]:
centroid = kmeans.cluster_centers_
print(centroid)


[[  62.1038807867   32.2720929412   22.9040926586]
 [  21.5117033512   72.129184157    31.2005839387]
 [ 144.9635573845   32.3298887365   14.188050602 ]
 [ 271.6812850422   31.1593735903   14.802378037 ]
 [ 445.1392788533   28.9411851633   15.244717009 ]
 [  25.8673038045   83.0735158978  350.1271825032]
 [ 725.6073224704   25.95332931     13.7479380406]
 [  21.6537735849  416.0235849057   98.8437106918]]

In [7]:
printKmeans(kmeans)



In [8]:
def updateQRST(wacentroid) :
    conn = psycopg2.connect("dbname=mimic")
    cur = conn.cursor()
    select_stament = """
    UPDATE rstq AS t
    SET
        centroid = s.centroid
        FROM unnest(%s) s(qt integer,ts integer,sr integer,centroid unknown)
        WHERE t.qt = s.qt
        AND t.ts = s.ts
        AND t.sr = s.sr;
    """
#    print(cur.mogrify(select_stament, (wacentroid,)))
    cur.execute(select_stament, (wacentroid,))
    conn.commit()
    conn.close()

In [9]:
def fillEmptyCentroids(iterations=1280) :
    waves = obtainMeasures(unlimit=True,centroid=None)
    print("measures obtained:"+str(len(waves)))
    waves = waves[:iterations] if iterations<len(waves) else waves
    numberToAlpha = dict(enumerate(string.ascii_lowercase, 0))
    i = 1
    centro = []
    for wave in waves :
        try:
            centValue = numberToAlpha[kmeans.predict([[wave[0],wave[1],wave[2]]])[0]]
            centro.append((wave[0],wave[1],wave[2],str(centValue)))
        except:
            print("error in value")
        i=i+1
    if centro != [] :
        updateQRST(centro)

In [10]:
fillEmptyCentroids(102400)


measures obtained:7414

In [11]:
def centroidColor(clist) :
    color = {
        'a': "blue",
        'b': "red",
        'c': "green",
        'd': "magenta",
        'e': "cyan",
        'f': "yellow",
        'g': "limegreen", 
        'h': "pink",
        None : "maroon"
    }
    return [color[x] for x in clist]

In [12]:
waves = obtainMeasures(unlimit=True,centroid="notNull")
qt = np.array([-item[0] for item in waves])
ts = np.array([item[1] for item in waves])
sr = np.array([item[2] for item in waves])
color = np.array([item[3] for item in waves])
qtc = np.array([-int(item[0]) for item in centroid])
tsc = np.array([item[1] for item in centroid])
src = np.array([item[2] for item in centroid])
color = centroidColor(color)
fig = plt.figure()
ax = fig.add_subplot(221)
ax.set_title("qt/ts")
ax.set_xlabel("qt")
ax.scatter(qt,ts, c=color)
ax.scatter(qtc,tsc,c='black', marker=">")
ax = fig.add_subplot(222)
ax.set_title("ts/sr")
ax.set_xlabel("ts")
ax.scatter(ts,sr, c=color)
ax.scatter(tsc,src,c='black', marker=">")
ax = fig.add_subplot(223)
ax.set_title("sr/qt")
ax.set_xlabel("sr")
ax.scatter(sr,qt, c=color)
ax.scatter(src,qtc,c='black', marker=">")
plt.show()



In [13]:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(ts,qt, sr, c=color)
ax.scatter(tsc,qtc, src, c='black',marker="^",s=160)
plt.show()



In [14]:
def findCentroid(centroid,window=0,dbname="mimic") :
    conn = psycopg2.connect("dbname="+dbname)
    cur = conn.cursor()
    qt = str(centroid[0])
    ts = str(centroid[1])
    sr = str(centroid[2])
    strWin = str(window)
    select_stament = ("SELECT rstq.record,r_s,q_s,a.rec_from,a.rec_to,wave,centroid "
                      " FROM rstq LEFT JOIN a ON a.record=rstq.record  "
                      " WHERE "
                      " (qt between floor("+qt+")-"+strWin+" and ceil("+qt+")+"+strWin+")"
                      " AND (ts between floor("+ts+")-"+strWin+" and ceil("+ts+")+"+strWin+")"
                      " AND (sr between floor("+sr+")-"+strWin+" and ceil("+sr+")+"+strWin+")"
                      " AND rstq.record not in ('mimic2wdb/matched/s23890/s23890-2832-10-25-12-55',"
                      " 'mimic2wdb/matched/s20486/s20486-2701-07-11-18-41') "
                      " LIMIT 1")
    cur.execute(select_stament)
    notFound = True
    for row in cur :
        notFound = False
        pbdir = row[0]
        wave = pbdir.split("/")[3]
        pbdir = pbdir.replace("/"+wave,'')
        return {"pbdir":pbdir,"onda":wave,"r_s":row[1],"q_s":row[2],"rec_from":row[3],"rec_to":row[4],"wave":row[5],"centroid":row[6]}
    if(notFound) :
        return findCentroid(value,window=window+1)

In [15]:
def updateOriginalWave(wave,originalWave):
    conn = psycopg2.connect("dbname=mimic")
    cur = conn.cursor()
    select_stament = ("UPDATE rstq SET wave = (%s) "
                      "WHERE record = (%s) AND r_s = (%s) AND q_s = (%s)")
    record=wave['pbdir']+"/"+wave['onda']
    print(record+"r_s"+str(wave['r_s']))
    cur.execute(select_stament, (originalWave.tolist(),record,wave['r_s'],wave['q_s'],))
    conn.commit()
    cur.close()
    conn.close()

In [ ]:
def printCentroid(wave) :
    onda = wave['onda']
    originalWave = wave['wave']
    if originalWave is None :
        sig, fields = wfdb.srdsamp(onda,pbdir=wave['pbdir'], sampto=1)
        signalII = fields['signame'].index("II")
        sfrom = wave['rec_from']+wave['r_s']-20
        sto   = wave['rec_from']+wave['q_s']
        #sto = sfrom+100 if sto-sfrom>100 else sto
        originalWave = wfdb.rdsamp(onda,pbdir=wave['pbdir'],channels =[signalII], sampfrom=sfrom, sampto=sto).p_signals
        originalWave = originalWave[~np.isnan(originalWave)]
        updateOriginalWave(wave,originalWave)
    ax.set_title(wave['centroid'])
    ax.plot(originalWave[:100])

In [ ]:
fig = plt.figure()
inx= 1
for value in centroid :
    ax = fig.add_subplot(3,3,inx)
    wave = findCentroid(value)
#    print("wave",wave)
    printCentroid(wave)
    inx=inx+1
plt.show()


mimic2wdb/matched/s15385/s15385-2732-04-27-15-47r_s125863

In [ ]: