310 likes | 430 Views
Facultad de Ingeniería UNIVERSIDAD DE MENDOZA Pasaje Descote750 5500 Mendoza República Argentina Teléfono 061-201872. Curso “ Experimentación con Bases de Datos de señales cardiológicas. Recursos de Physionet . ” DICTADO POR: dR. Ing. jesús Rubén Azor montoya 2011.
E N D
Facultad de Ingeniería UNIVERSIDAD DE MENDOZA Pasaje Descote7505500 MendozaRepública ArgentinaTeléfono 061-201872 Curso “Experimentación con Bases de Datos de señales cardiológicas. Recursos de Physionet. ” DICTADO POR: dR. Ing. jesús Rubén Azor montoya 2011
El WFDB Toolbox para MATLAB Esta es una colección de aplicaciones WFDB implementadas como funciones en MATLAB. WFDB es una aplicación que permite leer y escribir archivos en los formatos usados por PhysioBankdatabases. Por default, el Toolbox WFDB para Matlab soporta la lectura directa de registros desde el PhysioBank sobre la web. Por ejemplo, en MATLAB, se puede simplemente descargar y graficar una señal >> r = rdsamp('mitdb/100', 'maxt', ':10'); >> plot(r(:,1), r(:,2)); Lo cual permite obtener en una matriz r los datos del registro ubicado en la carpeta mitdb desde www.physionet.org.
El WFDB Toolbox para MATLAB Al momento, están implementadas las siguientes funciones: rdannLee archivos de anotaciones para registros WFDB sdsampLee archivos de señal WFDB de registros WFDB SetwfdbPone paths WFDB a valores default Time2secConvierte intervalos de tiempo formato WFDB en segundos wfdb_configretorna información de versión y compilación acerca de la librería WFDB Wfdbdescretorna especificaciones para señales en registros WFDB WfdbwhichEncuentra la locación de archivos pertenecientes a registros WFDB WrannEscribe anotaciones para registros WFDB en los archivos de anotaciones WrsampEscribe datos de señal en registros WFDB-compatibles
El WFDB Toolbox para MATLAB • La biblioteca WFDB ha evolucionado para apoyar el desarrollo de numerosas otras bases de datos que incluyen señales como • presión sanguínea, • Respiración, • Saturación de oxígeno, • EEG, así como ECG. • Entre estas bases de datos de múltiples parámetros están: • MGH/Marquette FoundationWaveformDatabase, • MITBIH • MIMIC Database. • De este modo, la biblioteca WFDB es mucho más que una interfaz de Base de Datos de ECG.
Registros (Records) Las bases de datos para las cuales fue diseñada la librería WFDB consisten de un pequeño número de registros, cada uno de los cuales es muy grande (típicamente Mbytes o más). Antes de 1990, los registros de la base de datos usualmente se originaban como grabaciones en cinta analógica, aunque muchas de las recientemente creadas son grabadas digitalmente en disco. Cada registro contiene una grabación continua de un único sujeto. Un programa de aplicación típica accede sólo a un único registro, y la mayoría (no todos) de los accesos dentro del registro es secuencial. Los registros son identificados por record namesde hasta 20 caracteres. Por ejemplo, record names en la MIT DB son números de tres dígitos. Un registro se compone de varios archivos, que contienen las señales, las anotaciones, y las especificaciones de los atributos de la señal, cada archivo perteneciente a un registro dado incluye normalmente el nombre del registro (record name) como la primera parte de su nombre.
Registros (Records) Las bases de datos para las cuales fue diseñada la librería WFDB consisten de un pequeño número de registros, cada uno de los cuales es muy grande (típicamente Mbytes o más). Antes de 1990, los registros de la base de datos usualmente se originaban como grabaciones en cinta analógica, aunque muchas de las recientemente creadas son grabadas digitalmente en disco. Cada registro contiene una grabación continua de un único sujeto. Un programa de aplicación típica accede sólo a un único registro, y la mayoría (no todos) de los accesos dentro del registro es secuencial. Los registros son identificados por record namesde hasta 20 caracteres. Por ejemplo, record names en la MIT DB son números de tres dígitos. Un registro se compone de varios archivos, que contienen las señales, las anotaciones, y las especificaciones de los atributos de la señal, cada archivo perteneciente a un registro dado incluye normalmente el nombre del registro (record name) como la primera parte de su nombre.
Señales, Muestras, y Tiempo Las señales son comúnmente comprendidas como funciones del tiempo obtenidas por observación de las variables físicas. En esta guía, una señal es definida más restrictivamente como una secuencia de muestras enteras, usualmente obtenidas de la digitalizacón de una función continua del tiempo observada a una frecuencia de muestreo fija expresada en Hz (muestras por segundo). El intervalo de tiempo entre cualquier par de muestras adyacentes en una señal dada, es un intervalo de muestreo. Todos los intervalos de muestreo para una señal dada son iguales. El valor entero de cada muestra es usualmente interpretado como una tensión, y las unidades son llamadas unidades de convertidor AD, o adu. La ganancia definida para cada señal especifica a cuántas adus corresponde una unidad física (usualmente 1 mV).
Señales, Muestras, y Tiempo Todas las señales en un registro dado están usualmente muestreadas a la misma frecuencia, pero no necesariamente con la misma ganancia. Los registros MIT DB están muestreados a 360 Hz; los AHA y ESC DB a 250 Hz. El número de la muestra (samplenumber) es un atributo de una muestra, se define como el número de muestra de la misma señal que lo precede, así el número de muestra de la primera muestra es cero. Dentro de esta guía, las unidades de tiempo son intervalos de muestreo, de ahí que el "tiempo" de una muestra es sinónimo de su número de muestra. Las muestras con el mismo número de muestra en diferentes señales del mismo registro son tratados como simultáneos.
Anotaciones (Annotations) Los registros MIT DB tiene cada uno 30 minutos de duración, y se anota en todos; con esto se quiere decir que cada latido (complejo QRS) se describe mediante una etiqueta llamada anotación. Típicamente un archivo de anotación para un registro MIT DB contiene cerca de 2000 anotaciones de latido, y números menores de anotaciones de ritmo y calidad de señal. Los registros AHA DB (AHA es una base de datos para evaluación de detectores de arritmia ventricular. )son o bien de 35 minutos o de tres horas de duración, y sólo los30 últimos minutos de cada registro son anotados. Los registros ESC DB (La base de datos European ST-T, consistente de 90 registros identificados por nombres con el prefijo ‘e’ y cuatro dígitos ) son cada uno de 2 horas de longitud, y se anota todo. El “tiempo” de una anotación es simplemente el número de la muestra con la cual está asociada la anotación. Las anotaciones pueden estar asociadas con una única señal, si se desea.
Lectura de archivo de anotación function [anns] = rdann(timeInSeconds record, annotator, ...) Lee el archivo de anotación para el registro especificado y anotador, y lo retorna como una estructura en forma de arreglo legible por humanos, con una entrada por anotación. Puede ser usada una opción ‘concisa’ para indicar, en su lugar, que sólo los tiempos de las anotaciones deben ser devueltos, en este caso, el valor de retorno no es una estructura amplia, sino una matriz de dos columnas. El arreglo de estructura no-concisa tiene los siguientes campos: timeInSeconds (number): El tiempo de la anotación en segundos sampleNumber (unit): El tiempo de la anotación en muestra typeMnemonic (string): El nemónico para el tipo de anotación subtype (uint8): el campo sub-tipo de anotación chan (uint8): el campo chan de la anotación num (uint8): el campo num de la anotación auxInfo (string): un string de información auxiliar para la anotación
Lectura de archivo de anotación Se requieren dos argumentos: record: el nombre del registro WFDB annotator: el nombre del anotador para el registro dado Seis argumentos opcionales (valores default en []s): 'start'(string tiempo-formato): el tiempo en registro desde el cual se comienza la lectura ['00:00:00'] 'stop' (string tiempo-formato): el tiempo en registro desde el cual se termina la lectura [end of record] 'chan' (int8): el número "chan" para anotaciones a ser retornadas (todas las otras anotaciones no son retornadas) [] 'num' (int8): el número "num" para anotaciones a ser (todas las otras anotaciones no son retornadas) [] 'subtype' (int8): el número "subtipo" para anotaciones a ser retornadas (todas las otras anotaciones no son retornadas) [] 'type' (1 o más strings): nemónicos de los tipos para anotaciones a ser retornadas (todas las otras anotaciones no son retornadas) [] 'concise' (0 ó 1 booleano): retorna sólo dos columnas: la primera de los tiempos de anotación, y la segunda de los números de muestra de la anotación
Lectura de archivo de anotación Ejemplos: clear >> % retorna todas las anotaciones del registro 'mitdb/100’ >> % con el anotador 'atr‘ >> A=rdann('mitdb/100', 'atr') 1x2274 struct array with fields: timeInSeconds sampleNumber typeMnemonic subtype chan num auxInfo Se observa que A es una estructura cuyos valores se averiguan para el campo timeInSecondslos 10 primeros valores se hallan con: >> for i=1:10;B(i)=A(i).timeInSeconds;end
Lectura de archivo de anotación Para sacar los datos del registro como un arreglo, se puede utilizar el siguiente segmento: A=rdann('mitdb/100', 'atr'); B=0; for i=1:10; B(i,1)=A(i).timeInSeconds; B(i,2)=A(i).sampleNumber; B(i,3)=char(A(i).typeMnemonic); B(i,4)=char(A(i).subtype); End Parte del arreglo B es: >> B(1:5,2)‘ ans = 18 77 370 662 946 >> char(B(1:5,3))‘ ans = +NNNN
Lectura de archivo de anotación Para sacar los datos del registro como un arreglo, se puede utilizar el siguiente segmento: D=rdann('mitdb/100', 'atr', 'type', 'A', '+'); B=0; for i=1:10; B(i,1)=D(i).sampleNumber; B(i,2)=char(D(i).typeMnemonic); end Parte del arreglo B es: >> B(1:3,1)',char(B(1:3,2))‘ ans = 18 2044 66792 ans = +AA Otroejemplo: % retorna todas las anotaciones del registro 'mitdb/100' entre % 1 min. y 1 min. 30 seg., con chan 0 y subtype 0 rdann('mitdb/100', 'atr', 'start', '00:01:00', 'stop', ... '00:01:30', 'chan', 0, 'subtype', 0)
Lectura de archivo de señal function [S] = rdsamp(record, ...) Lee archivos de señal WFDB para el registro especificado y retorna las muestras como vectores columna. La Columna 1 de la salida es siempre un vector del número de muestra. Las columnas remanentes son vectores de las señales del registro. Se requiere sólo un argumento: record: el nombre del registro WFDB. Tiene seis argumentos opcionales (valores default en []s): 'begin' (string tiempo-formato): el tiempo en el registro desde el cual se empieza a leer ['00:00:00'] 'maxt' (string tiempo-formato): límite superior en tiempo, sobre la cantidad de salidas producidas [no limit] 'stop' (string tiempo-formato): el tiempo en el registro desde el cual se empieza a leer ['00:00:00'] [end of record]
Lectura de archivo de señal 'hires' (booleano): si o no lee en modo alta resolución; idéntico para registros ordinarios, sino para registros multifrecuencia, la decimación estándar de sobremuestreo para la framerate es suprimida (todas las otras señales son remuestreadas a la más alta frecuencia de muestreo [false] 'phys' (booleano): si o no retorna valores de señal como aquellos de sus respectivas unidades físicas, en vez de unidades A/D crudas [false] 'sigs' (1 o más uint32's): los números de señal de las señales a ser retornadas (0-indexado) [todos los números de señal, en orden] Note que los valores de 'begin', 'maxt', y 'stop' se espera que sean “strings formato- tiempo" de la forma 'AB:CD:EF' (donde A a F representa dígitos simples); e.g., '00:00:00' representa tiempo cero, '00:00:05' cinco segundos, '00:05:00' cinco minutos, y así siguiendo. El valor de 'maxt' es estrictamente un límite superior: si la longitud de tiempo entre 'begin' y 'stop' es mayor que 'maxt', entonces el tiempo de parada actual es 'begin' + 'maxt'. Los argumentos opcionales se especifican como parámetro/valor, donde el parámetro es un string.
Lectura de archivo de señal Ejemplos % retorna todas las señales del registro 'mitdb/100‘ en r r=rdsamp('mitdb/100'); size(r) ans = 650000 3 Si se quiere ver gráficamentelaprimeraderivación: x=r(1:1000,1);y=r(1:1000,2); plot(x,y)
Lectura de archivo de señal % retorna todas las señales del registro 'mitdb/100', % en unidades físicas r=rdsamp('mitdb/100','phys',true); x=r(1:1000,1);y=r(1:1000,2); plot(x,y)
Lectura de archivo de señal % retorna todas las señales del registro 'mitdb/100', en modo % high-res, comenzando en 10 segundos desde el arranque, y terminando en 2 min. 30 seg. desde el arranque R1=rdsamp('mitdb/101','begin','00:00:10','stop','00:02:30','hires',true); R1(1:3,1:3) ans = 3600 952 1004 3601 954 1002 3602 957 1003 % retorna solo la primera señal (i.e. "numero cero") de % 'mitdb/101' R2=rdsamp('mitdb/101','sigs',1); R2(1:3,:) ans = 0 992 1 992 2 992
Conversión a segundos function [s] = time2sec(time, ...) Convierte un string tiempo-formato en un número de segundos Si el string tiempo-formato dado es encerrado entre corchetes (por ejemplo, '[9:0:0]') y si el registro está dado (como un argumento opcional), entonces el valor retornado es el tiempo transcurrido desde el comienzo del registro. Se requiere un argumento: time: el string tiempo-formato indicando el tiempo a convertir Un argumento opcional: 'record' (string): el registro sobre el cual basar la conversión, si es requerida la conversión time-of-day, como se describe debajo
Escritura de archivo de señal function [] = wrsamp(cols, record, ...) Crea un registro con datos y nombre dados. La creción de un nuevoregistroimplica la creación del archivollamado [record,'.dat'], y el archivollamado [record,'.hea']. wrsamp()puede ser usadocasicomounarelacióninversa a rdsamp), exceptoquemientras la primer columnaretornadaporrdsamp()es un vector de números de muestras, lascolumnaspasadasporwrsamp() son sóloseñales de datos. Nada esretornado. Se requieren dos argumentos: cols: lasseñales a escribir, comovectorescolumna record: el nombre del registro a crear
Escritura de archivo de señal function [] = wrsamp(cols, record, ...) Crea un registro con datos y nombre dados. La creción de un nuevoregistroimplica la creación del archivollamado [record,'.dat'], y el archivollamado [record,'.hea']. wrsamp()puede ser usadocasicomounarelacióninversa a rdsamp), exceptoquemientras la primer columnaretornadaporrdsamp()es un vector de números de muestras, lascolumnaspasadasporwrsamp() son sóloseñales de datos. Nada esretornado. Se requieren dos argumentos: cols: lasseñales a escribir, comovectorescolumna record: el nombre del registro a crear
Escritura de archivo de señal Hay sieteargumentosopcionales (valores default en []s): 'inputname' (string): si no-nulo, estoesusado en la descripción (el campo 'desc') de cadaseñal [null] 'dither' (boolean): si o no vacilar (dither) los datos en columnas antes de convertirlo a salidaentera [false] 'start' (uint): el número de muestradesde la cualcomenzar a escribir, con índice 0-based; todos los datosanteriores son ignorados [0] 'stop' (uint): el número de muestradesde la cualparar de escribir; sólo los datosanteriores a ella son usados [end of data, en estecaso, size(cols,1)+1]
Escritura de archivo de señal 'freq' (number): la frecuencia de muestreo de cadauna de lasseñales, en muestrasporsegundo; sóloafecta la escritura del archivo de cabeceraescrito [250] 'gain' (0 o másnúmeros): la ganancia (en unidades A/D pormilivoltio) de lasseñales; valoresmúltiplespueden ser dados, hasta el número de señales, y si N valores son dados para M señales y N < M, todaslasseñalesdespués de la N-ésimatendrán la mismagananciaque la N-ésima; sóloafecta la escritura del archivo de cabeceraescrito [200] 'scale' (0 o másnúmeros): un factor por el cualescalartodaslasmuestras en lasseñales; multipleavalorespueden ser dados, comportando exactamente como "ganancia" por encima para señales múltiples; afecta a la archivo de datos al cambiar la señal de datos [1]
Escritura de archivo de señal Ejemplo: % adquieredatosexistentes d = rdsamp('mitdb/100','begin','00:00:00','stop','00:01:00'); % sacaunacopia del registro 'mitdb/100', llamado ‘100copy', % consistente de archivos locales ‘100copy.dat' y % ‘100copy.hea’ note quesaltamos la primeracolumna % retornadaporrdsamp()(los números de muestra) wrsamp(d(:,2:3), '100copy'); % triplica la primeraseñal del registro 'mitdb/100', y % escribeestas al registro ‘100dup'; saltalasprimeras % 10 muestras wrsamp([d(:,2), d(:,2), d(:,2)], '100dup', 'start', 10)
Escritura de archivo de señal Para verificar lo ocurrido, se tipean las siguientes instrucciones: % Lectura del archivo 100copy r2=rdsamp('100copy');r2(1:5,1:end)‘ ans = 0 1 2 3 4 995 995995995995 1011 1011101110111011 % Lectura del archivo 100dup r1=rdsamp('100dup');r1(1:5,1:end)‘ ans = 0 1 2 3 4 995 994 992 993 992 995 994 992 993 992 995 994 992 993 992
Escritura de archivo de anotación function [] = wrann(annots, record, annotator) Dado un vector columna de anotaciones, escribe un nuevoarchivo de anotaciónpara un registro. El archivo de anotaciónesescritolocalmente, usando el nombre de registrocomo la base del nombre de registro, y el nombre del anotadorcomosuextensión. Nada esretornado. Se requierentresargumentos: annots: un arregloestructura vector columnamanteniendolasanotaciones a escribirfuera; el formato del arregloestructuradeberá ser exactamente el mismocomo el retornadoporrdann(), y se describe debajo. record: el nombre del registro al cualescribir el archivo de anotación annotator: el nombre del anotador; estambién el sufijo del archivo de anotación.
Escritura de archivo de anotación El arregloestructuraannotsdeberátener los siguientescampos: timeInSeconds(number): el tiempo de lasanotaciones en segundos sampleNumber (uint): el tiempo de lasanotaciones en muestras typeMnemonic(string): los mnemónicospara el tipo de anotación subtype(uint8): el campo subtype de anotación chan(uint8): el campo chan de anotación num (uint8): el campo num de anotación auxInfo (string): un string de informaciónauxiliarpara la anotación
Escritura de archivo de anotación Examples % Se adquierenanotacionesexistentes a = rdann('mitdb/100', 'atr'); % escribeanotacionespara el registro 'mitdb/100', al archivo % de anotación local wrann(a, '100', 'atr'); Si se quiere leer los primerosvalores de ‘100’: >> b = rdann('100', 'atr'); b(1).timeInSeconds, b(1).sampleNumber ans = 0.0500 ans = 18
Encontrar ubicación de archivos function [fp] = wfdbwhich(filename) function [fp] = wfdbwhich(filename, 'record', substRecord) function [fp] = wfdbwhich(filetype, record) Busca la senda (path) para el archivo con un nombreespecífico o para el archivo con un file type dado en un registro dado. wfdbwhich()puede ser llamada de tresformas . wfdbwhich(filename)busca el path WFDB y retorna la ubicaciónplena del nombre de archivo (filename), siesencontrada. wfdbwhich(filetype, record)buscapor un archivo dado quetengaunaextensión dada porfiletype (un string), en el registro dado. wfdbwhich(filename, 'record', substRecord)puede ser usadocuando el path WFDB acesiblemediantegetenv('WFDB')contiene el string '%r', en cuyocaso se comportatalcomowfdbwhich(filename) exceptoquesustituyesubstRecordpor '%r' en el path. Para cualquiera de los trescasos, si un path no se encuentra, se retorna el ([]).
Encontrar ubicación de archivos Examplos: % encuentra el archivo llamado '100.dat‘ fp = wfdbwhich('100.dat') fp = http://physionet.org/physiobank/database/mitdb/100.dat % encuentra el archivo de tipo 'hea' (header), en % el registro 'mitdb/100' fp = wfdbwhich('hea', 'mitdb/100') fp = http://physionet.org/physiobank/database/mitdb/100.hea