BrunoProg64 Blog

Sonic R bajo Windows 7 – Análisis Técnico

Posted by brunoprog64 en enero 8, 2011

Sonic R, es un juego desarrollado por Traverlers Tales en 1997 tanto para la Sega Saturn (Una especie de Play Station 1 de SEGA) y PC. Es un juego de carreras y es “infame” por su “azucarda” música (En especial el track “Can you Feel the Sunshine?” y tener asociado a él, la maldición del Tails Doll.

Bueno, por tanto hablar, se me metió la curiosidad de que si realmente una maldición de videojuego pueda matarte. Pensándolo bien… podría ser una muerte “a la” Fringe, como esta de aquí, del Episodio 1×12.

Y bueno, tras pensármelo un rato, decidí bajarme el ISO del Juego de PC… y lo instalé. Y bueno, cuando quize ejecutar el juego, tuve esta “linda” imagen.

Error del Sonic R bajo Windows 7

Error del Sonic R bajo Windows 7

Y bueno, lo intenté ejecutar en máquina virtual de Windows XP… y el mismo error. En modo de Compatibilidad de Windows 95, y lo mismo. Si presiono Enter y lo ejecuto muchas veces, carga… pero luego se cuelga igual. No había forma posible de poderlo jugar en mi PC. Y no pienso usar una Pentium 3 para jugar Sonic R.

Pues bueno, buscando en YouTube y similares encontré una posible solución para el juego. En estos tres videos: Este, este y este.

Bueno, yo he tenido que hacer las tres soluciones. Les menciono rápidamente que problemas daba el Sonic R en mi sistema:

  • Primero… cuando el juego se “lograba” ejecutar, se iba a pantalla completa y se colgaba ahi. No podía salir… así que normalmente hacía Reset.
  • Segundo, si el juego corría, se colgaba en la pantalla de presentación o en el  “Pulsa Start”.
  • Tercero, en la máquina virtual, producía un pantallazo azul en la Máquina Virtual.

Entonces, el problema para “investigar” al juego, era que si lo ejecutaba, se me colgaba en Pantalla Completa y me colapsaba toda la máquina. Así que tenía que ubicar una forma de hacerlo funcionar en una ventana, por si fallaba y así lo podría cerrar y no comprometer mi trabajo previo.

Para eso ubiqué un programa llamado DX-WND-MS, un software que ponía en ventana el Maple Story al interceptar las APIs de DirectX que usa para la pantalla completa. Lo encontré en un servidor com mucho captcha y tonterías similares, así que lo subo a un sitio más directo como MediaFire. Pueden bajarlo aquí.

Internamente este programa trabaja haciendo “hooks”  a las funciones que ponen resolución al “lienzo” DirectX, indicándoles que será una ventana y no la pantalla entera. Aunque no se mucho de DirectX yo en realidad, los interesados en Hooks pueden leer este artículo al respecto.

Bueno, y en ese programa, agregamos nuestro juego (Ubicado en C:SEGASonic Rsonicr.exe) y dejamos corriendo ese programa, de modo que si hacemos algo mal, no nos reseteará o colgará la máquina. Ese paso ya es algo para poder seguir experimentando la razón de los erroes.

Ahora… según uno de los videos, esa era la solución. No la fue en mi caso, el programa seguía crasheando apenas inicia. Entonces hagamos algo más… laborioso. El error del juego dice que en la posición de memoria 00481d09 ha ocurrido un error. ¿Y que hay en esa zona de memoria?

Para eso tenemos que bajarnos un programa llamado W32Dasm, el cual nos permitirá desensamblar nuestro ejecutable. Pueden bajarlo aquí. Y bien, abriremos con ese software nuestro archivo sonicr.exe y en el Menú Goto -> Goto Code Location y apuntamos 0041d09. Y el W32Dasm nos llevará a este lugar:

Desensamblado de Sonic R - Pos. 004801D9

Desensamblado de Sonic R – Pos. 004801D9

La línea en cuestión (Marcada en rojo) menciona un “idiv ecx”. ¿Y qué es eso? Bueno… eso es ensamblador o lenguaje ASM, así que nos vamos a Google y preguntamos que es eso de IDIV ECX.

Aquí nos explican que IDIV es una instrucción que hace que se divida el registro EX, AL o EAX contra el operando (En nuestro caso ECX) y guarda el resultado en EDX o EAX. Para explicarlo claro a los que no entienden ni papa de lo que dije:

Todo microprocesador tiene registros auxiliares (EAX, EDX, etc) y en lenguaje ensamblador estas son operaciones de muy bajo nivel, por lo que se realizan en pocos registros. Y… ¿Cuál es el error que hace que una división salga mal? La única que se me ocurre… es la división por cero.

Pero esperen… miren abajo… ahí pone… “CalculateClockSpeed”. ¿Qué está intentando hacer el programa? Ni idea, porque no domino el ensamblador. Pero seguramente es algo de calcular la velocidad del procesador, a juzgar por el nombre de la función. ¿Saben cómo podemos confirmarlo? Usando un depurador. Así que ahora, nos conseguiremos el Ollydbg, el cual se baja de su página oficial.

Importantísimo tener el DX-WND-MS corriendo para que no nos malogre la ventana… porque un depurador ejecuta el juego, no como el desensamblador que nos permitía verlo estáticamente.

En el Ollydbg, ponemos un Breakpoint en la posición de 004801D9, tipeando el comando

bp 004801d9

Pulsamos F9 para cargar el juego y el Ollydbg hará un alto en esa instrucción. Veremos esto:

Ollydbg y Breakpoint en Sonic R - Pos. 004801D9

Ollydbg y Breakpoint en Sonic R – Pos. 004801D9

Fijémonos en los contenidos de la memoria. Vean que en la ventana de Registro se ve “O – 1” y “C – 1”, eso indica que el flag de Overflow está activado al igual que el de Acarreo. Eso quiere decir que estamos a punto de tener un desbordamiento de enteros… y por eso falla el juego.

¿Y si cambiamos los flags a 0? (Doble click sobre sus letras) Si lo hacemos, veremos que no sirve de nada. Analicemos un poco más…

Obseven en EAX. Doble click y verán que el valor de EAX está totalmente desbordado. (Signed: -1844771072 y Unsigned: 2450196224) Eso explica los flags de Overflow y Acarreo. EDI también está desbordado…

Entonces cambiar a ciegas EAX no nos ayudará. Hay algo raro en el comportamiento de este programa que lo hace fallar. Según los videos de YouTube es la función WIMM.timeGetTime. En realidad yo no soy muy conocedor de ensamblador, así que asumiremos que eso es. Así que según el video, preparamos un Breakpoint en donde es llamada esa función, en la posición de memoria: 00480184. (Dejemomos nuestro Breakpoint en IDIV, sólo por curiosear) Con Ctrl + F2, reiniciamos el depurador.

Según la solución del video, el objetivo de la solución es provocar demora entre esas instrucciones para que no se desborde IDIV. Bueno… curiosaremos en los registros para ver si es eso o no. Ahora lanzamos el sonicr.exe otra vez…

Y volvimos a parar en la posición 00480184. Miremos a EAX. Indica un valor de 5276, por lo que no está desbordado. (Los valores Signed y Unsigned son idénticos y el flag O y C están en 0).  Presionamos F9 para seguir ejecutando… y paramos en 004801D9. Miramos y vemos los bits de Acarreo y Desbordamiento activados, pero seguimos con F9 y el juego no se cuelga. La razón es que IDIV divide por signo y si el resultado es muy grande para caber en el registro destino, el juego se cuelga. Con el delay, hemos prevenido esto, pero aún no estoy 100% convencido. Tendría que leer un poco de Ensamblador otra vez… y eso quedará para nuestro otro artículo.

Al final, logramos esto:

Sonic R - Ejecución Exitosa

Sonic R – Ejecución Exitosa

Y la ansiada carrera… también la logramos:

Sonic R - Carrera con Tails

Sonic R – Carrera con Tails

No sé si podré desbloquear al Tails Doll. El punto es que hemos logrado ejecutar Sonic R en Windows 7. El único inconveniente, es que será algo lento… pero nada del otro mundo.

En resumen… para los que quieren hacer esto en el Ollydbg:

  1. Primero, Breakpoint en 004801D9.
  2. Luego buscar la primera llamada a WIMM.timeGetTime y hacer un breakpoint ahi (En 0048184)
  3. Quitar el primer Breakpoint, salvo que quieran estudiar la razón del error.
  4. Presionar F9 repetidas veces para que haya un delay o demora y el juego pueda dividir bien.
  5. Jugar Sonic R.

Los tutoriales mencionaban usar IDA Pro, que es otro muy buen debugger, pero al cual no estoy acostumbrado… y es “comercial”. Ollydbg es más ligero y hace lo mismo prácticamente.

Si logro entender la causa del error de división, lo haré saber en este post. Ah… y me olvidaba, si quieren oír la infame “Can you feel the Sunshine?” deben jugar con el ISO o CD montado. No funciona sin su CD. El Crack No-CD es otra cosa… que no se ni explicar ni hacer.

Posted in Bilis, Opinion, Programacion, Windows | Comentarios desactivados en Sonic R bajo Windows 7 – Análisis Técnico

Proyecto de Tesis de ECG – Parte 2

Posted by brunoprog64 en junio 2, 2010

Me disculpo ante mis lectores por el retraso con el post, pero múltiples problemas impidieron que pudiera hablar con mis asesores a tiempo. De todos modos, espero compensar en esta Parte 2. Como siempre, esto viene de la Parte 1.5 publicada anteriormente.

Volvamos a nuestro tema, que es el de Tesis. Mis asesores han encontrado una multitud de problemas en mis teorías para la creación del ECG. Trataremos de corregir todo lo que pueda ser posible corregir…

Primero… me dijeron algo sobre el muestreo. Pues bien… resulta que había obviado algo que era de primer año de carrera: El Teorema de Muestreo de Nyquist-Shannon. Básicamente y en lo que me interesa saber, dice que si quiero muestrear un rango de frecuencias digitalmente, dicha frecuencia de muestreo debe ser el doble del original. Un ejemplo práctico donde verlo: La mayoría de MP3 están sampleados a 44.44 Khz. Pero… ¿La voz humana no es hasta los 22 Khz? Es por este Teorema. Es decir… debo muestrear al doble de lo que originalmente pensaba muestrear. Dado que la velocidad del ECG es de 25 mm/s, estamos hablando de 0.04 segundos de ECG por milímetro. En las bases de datos tipo MIT-BIH se samplea a 360 Hz mas o menos. Según estas diapositivas de Biopac Systems, ellos recomiendan 200 Hz para ECG o inclusive 1000 Hz en el caso de que se presente variabilidad del ritmo cardíaco. (Lo más común)

Por si alguien me critica por creerle a una empresa y no a los papers científicos, decir que por mentir se arriesgan a una señora demanda de la FDA en EE.UU, pero de todos modos este paper dice que sampleando a 500 Hz podemos meter el ECG veterinario dentro de un MiniDisc y este de aquí dice que mientras no bajemos de 62.5 Hz los algoritmos de detección no presentan graves errores. Así que las recomendaciones de Biopac Systems son de lo más sensato posible. Sigámoslas pues…

Me quedo con que 500 Hz es el sampling adecuado para un ECG (Vale, el paper es veterinario, pero… ¿Cuál es el problema?) y por el Teorema de Nyquist-Shannon: 500×2 = 1000 Hz. ¡La recomendación de Biopac Systems! Ah una cosa… a más sampling, más pesan los ECGs. Pero vamos… hoy día tenemos discos duros y USBs de GBs de tamaño… no seamos tan extremistas. Algo más sensato o mas mesurado sería bajar hasta los 200 0 360 Hz. El bitrate por sample es otro tema, aunque las bases de datos MIT-BIH usan 11 bits de sampling. Usemos ese valor.

Ya solucionamos entonces el detalle del muestreo: 1000 Hz por derivación y dada la multiplexión que mencioné la otra vez… hablamos de 3000 Hz por que usaremos Derivaciones I, II y III.

¿Recuerdan que dije que usando la Desviación Estándar podíamos verificar si un ECG era similar a otro? Pues bien… la idea es esa… ¡Pero está mal planteada! Una simple desviación estándar no garantiza que otra señal de similar distribución no se confunda por nuestro ECG. ¿Y eso como puede ser…? Veamos este caso:

  • 10, 20, 90, 80
  • 120, 40, 120, 60

Esta serie de números no se parecen en nada si las mostramos en una gráfica. Sin embargo la Desviación Estándar de ambas es de aproximadamente 41. (En realidad una es 40.82 y la otra 41.23), por lo que vemos que la Desviación Estándar no es una forma válida de decir si una señal es igual o similar a otra. Para hacer este trabajo habrá que usar otra cosa… algo llamado Prueba o Contraste de Hipótesis. De todas las posibles formas que hay para realizar un Contraste de Hipótesis, se me recomendó usar la Prueba T de Student, llamada así porque quien la ideó, William Gosset, publicó sus papers bajo el seudónimo de “Student”, porque no podía permitir que su empresa descubriera que ideaba sus teorías usando los datos de ventas de dicha compañía.

Hasta el momento podemos decir “que fácil, ya sé que fórmulas aplicar y con eso escribo en el Matlab”. Esperen todos… lametablemente la Prueba T de Student, asume ciertas cosas sobre el modelo y si lo trabajamos pensando en esas presunciones… los resultados serán estadísticamente inválidos y nos echarán la Tesis por la cara cuando al revise un jurado. Lo siento… pero es así de cruel. Así que nos armamos de paciencia y leemos sobre las asumsiones de la Prueba T de Student.

  • Varianza idéntica o varianza distinta
  • Distribución Normal de la muestra

La fórmula de la Varianza varía, pero eso es algo que fácilmente podemos hacer en Matlab averiguando la varianza de las dos derivaciones primero. Sin embargo para la Normalidad, deberemos usar la Prueba de Normalidad de Kolmogorov-Smirnov. Si esta prueba da positivo, sabremos que se sigue una distribución normal y podremos aplicar la fórmula T Student. Felizmente para todos, casi todo en el mundo sigue la Distribución Normal y los ECGs por lo que parece, no son la excepción. Otra cosa es que la Prueba T de Student tiene una “sensibilidad” o un rango de error que considerará admisible. Matlab lo asume en 0.05 %, suficiente para nuestros propósitos, pero lo dejo en claro porque paquetes como SPSS o cuando lo desarrollemos delante del jurado nos preguntarán por dicho valor.

Queda dicho esto para corregir la tontería del otro post que ya edité reflejando el error. Tal vez alguno se preguntará porqué hago tanto palabreo, cuando en Matlab un par de líneas arreglan el problema. De nuevo, digo que somos Ingenieros y como tales, al menos debemos ser capaces de justificar ante nuestro jurado el porqué de nuestras acciones. Además como hablamos de ECG, mientras mas minucioso mejor. Así los estadistas, quienes revisan de momento mi marco teórico me corregirán si meto la pata otra vez…

Vamos a ver un ejemplo con Matlab de lo que les digo… porque mucha teoría… pero ejemplos también ayudan… nos basaremos en la excelente ayuda que da Matlab, en nuestro caso sobre la Prueba T Student aplicada a 2 variables.

Usaremos el mismo archivo de la otra vez, el .mat de las 12 derivaciones. En nuestro caso extraeremos sólamente las derivaciones I, II y III.

%%cargamos el archivo ecg_raw.mat
load 'ecg_raw.mat'
ecg_raw = val;
clear val;

%el archivo tiene las derivaciones en orden: i, ii, iii, avr, avl, avf,
%v1, v2, v3, v4, v5, v6

der1 = ecg_raw(1,:);
der2 = ecg_raw(2,:);
der3 = ecg_raw(3,:);

%ya tenemos las tres derivaciones, comprobamos si el ECG esta en orden....

der2_tmp = der1 + der3;

if (std(der2_tmp) ~= std(der2))
  %varianzas distintas
  r1 = ttest2(der2_tmp,der2, 0.05, 'both', 'unequal' );
end

disp(['El resultado de la Prueba T Student es ', num2str(r1)]);

El resultado que debemos obtener debe ser el siguiente:

El resultado de la Prueba T Student es 0

Si el resultado fuese ‘1’, sabremos que no se validó la hipótesis de que A era semejante a B, con un 0.05 % de error y sabremos que los electrodos están mal posicionados. Con eso ya hemos corregido las metidas de pata garrafales del otro post en el que erroneamente mencionaba a la Desviación Estándar.

Ahora en las nuevas cosas que se me pidió, fue que enfocáramos el tema a la Ingeniería de Sistemas y no a la Medicina, en mi caso, que definieramos una metodologia, un índice y los nombres de loas asesores. Así mismo se me solicitó que hiciera una especie de planteamiento o situación problemática. Vamos a responder una por una a estas dudas.

Enfoque del Trabajo: No pienso hablar en mi trabajo de Infartos, Isquemias y demás, salvo el obligatorio capítulo en el que mencionare brevemente el tema médico. Mi tema aquí no se trata de establecer una herramienta precisa de diagnóstico… sino de implementar por software una lectura de ECG y su extracción de características, como intervalos de Onda QRS, cantidad de latidos por segundo y demás. Luego dichos valores se pueden comparar con archivos de texto donde están registradas las anomalías en estos detalles que se correlacionan con enfermedades cardíacas o condiciones especiales del corazón y el programa muestra una alarma. Así que… si… nos enfocaremos a la Computación más que a la Medicina.

Indice Tentativo del Trabajo:

  • Introducción
  • Capítulo 01: Introducción a la Electrocardiografía (ECG) y Oximetría
    • Triángulo de Einthoven
    • Las 12 derivaciones del ECG
    • Las 6 primeras derivaciones: I, II, III, aVR, aVF y aVL.
    • Foto-Oximetría
  • Capítulo 02: Diseño del capturador de ECG y Oximetría
    • Colocación de los 3 electrodos
    • Multiplexación basada en tiempos.
    • Tratando el ECG como una señal de audio.
    • Diagrama de Circuito de capturador ECG.
    • Instrucciones de construcción.
  • Capítulo 03: Filtrado de la señal de ECG
    • Amplificación de la Señal de ECG
    • Filtrado de ruido
    • Interferencia de 60 Hz.
    • Filtro de suavizado Savitzky-Golay
  • Capítulo 04: Reconocimiento de Patrones de ECG
    • Detección de Complejos QRS
    • Contando los latidos
    • Detectando la Saturación mediante la Oximetría
    • Caracterización de las patologías cardiacas de las 6 primeras derivaciones.
  • Conclusiones
  • Bibliografía

Posiblemente la Oximetría la acabe excluyendo, aunque medir el nivel de oxígeno suele ser útil en ciertos casos. Dado que nada aporta el nombre de los asesores a este blog, los mantendremos en la más absoluta reserva.

Planteamiento y Situación Problemática:

Hay que distingir las razones académicas o que van en el papel, con las que realmente me impulsan a esto. En mi caso las últimas ya las discutimos en el primer post cuando hablé de Daniel Stark, así que vamos a las académicas:

La propia OMS reconoce que las Enfermedades Cardiovasculares, matan a un promedio de 17.1 millones de vidas al año. Sobre las razones de riesgo hay que decir que las mujeres y hombres casi por igual, los países subdesarrollados, el tabaco, el alcohol, la vida sedentaria, el sobrepeso, la diabetes y demás son indicadores más significativos.

Detengámonos un momento en “países subdesarrollados“. Es decir que una de las razones probables de que esto pase es la falta de equipo diagnóstico. En realidad las causas son más alimenticias y por el uso de drogas como el alcohol y el tabaco, pero centrémonos en el problema diagnóstico. Esto quiere decir que si se tuvieran más equipos de monitoreo coronario (No sólo ECGs) se podrían detectar o tratar a tiempo las afecciones cardiacas, porque estas casi siempre son reversibles.

¿Y si el ECG no es rutinario, porque no es fácil conseguirlo para los médicos? Si desarrollásemos un ECG que fuera efectivo y barato, podríamos hacer más accesible la prueba a cualquier persona con los conocimientos de electrónica para construya el equipo. ¿Y porqué lo hacemos por software? Porque podemos ahorrar cierta cantidad de dinero usando hardware de propósito general haciendo el producto más accesible a quienes lo necesiten. Además, así podemos construir una Base de Datos que se puede ir extendiendo sobre las condiciones del corazón.

¿Y eso que tiene que ver? Mucho tiene que ver… al hacer eso, podemos convertir el Sistema en extensible y podemos abarcar más y más situaciones. Un ejemplo: Dopping. Básicamente se usan drogas que aumentan el desempeño metabólico. Estas drogas deben mostrar ciertos trazos en el ECG (Así como lo hace la digital, por ejemplo). Las pruebas de orina son útiles, pero pueden llegar a ser caras. Si se encontrase un patrón de ECG que se relacionase con el dopping de ciertas sustancias, sólo es cuestión de agregar la data a nuestra base de datos. En otros productos, se podría requerir un equipo específico o la pericia del médico, ya que no siempre los ECGs comerciales interpretan la señal que captan.

Naturalmente y lo diré fuerte, esto SE DESARROLLA CON PROPÓSITOS EXPERIMENTALES. Nada que ver con que sustituya al médico o permitir a un no médico el diagnosticarse el solito. Nada que ver… esto puede ayudar al médico que si lo considera, podría editar los archivos de datos de diagnósticos y hacer el sistema más preciso. Pero todo esto, como cualquier investigación es experimental y sujeto a riesgos. A pocos realmente, ya que el ECG es una prueba no invasiva, pero hay riesgos en que se den falsos positivos, porque los hay.

Finalmente decir que sigo abierto a sugerencias y correcciones. Seguiremos con la Parte 3 o 2.5 en cuando culmine la revisión de estas ideas que les digo.

Posted in Opinion, Papers, Personal, Programacion, Tesis | Comentarios desactivados en Proyecto de Tesis de ECG – Parte 2

Proyecto de Tesis de ECG – Parte 1.5

Posted by brunoprog64 en mayo 5, 2010

Saludos de nuevos a mis lectores. Esta parte sigue de la Parte 1, anteriormente publicada y se llama “1.5” porque he de corregir ciertas cosas que no quedaron clara en la misma.

Primero, sobre lo de la presión y que sube y baja en respuesta a emociones. Existe en Medicina el caso de Hipertensión de la Bata Blanca, que es un caso pasajero de hipertensión cuando un paciente está ante su médico, por ansiedad. La existencia del síndrome confirma parcialmente mi teoría de que la subida de tensión es provocada por razones emocionales. Sin embargo no he encontrado nada que diga exactamente que la ansiedad sube la tensión y el miedo la reduce. Es dependiente de cada persona… por lo que me corrijo de los párrafos del primer artículo. No necesariamente la tensión sube o baja de acuerdo a ansiedad y miedo. Y dado que no pienso hacer el medidor de tensión en mi monitor ECG de momento, lo retiro de mi proyecto oficial.

De nuevo, estos post no son necesariamente lo que diré ante los jurados, porque quiero acercar a mis lectores al tema de hacer una Tesis, sin ser tan formales, que a mi parecer es el grave problema que padecen los centros de enseñanza. Pero volvamos al tema, no nos desviemos.

He decidido complicarme un poco la vida… y he vuelto con una novedad. Recuerdan que dije en el otro post que aVF, aVL y aVR, son derivaciones que se pueden calcular ya que el Triángulo de Einthoven cumple las Leyes de Kirchhoff. Einthoven promulgó una Ley, llamada la Ley de Einthoven, que nos dice que la suma de las Derivaciones I y III da igual a la Derivación II. Si esto no fuera así, los electrodos están mal colocados. Normalmente los ECGs comerciales calculan la Derivación II como es normal, pero ya hemos dicho que nuestro gran problema en mi caso es que sólo disponemos de una entrada de audio con dos canales. Pues sólo usaremos dos derivaciones: I y III y calcularemos la II por la Ley de Einthoven. La denoto mejor:

II Derivacion = I Derivacion + III Derivación

Naturalmente podemos despejar la ecuación para obtener la I o la III Derivación, de modo que tengamos que poner el menor número de electrodos posibles. Dirán algunos que esto disminuye la exactitud del ECG… es cierto. No es lo mismo una Derivación sacada por matemáticas, que la Derivación sacada por sensores. Pero… no todo es lo que parece. Más adelante lo explicaré.

Volviendo a Einthoven… él no es el descubridor de las derivaciones aVR, aVL, aVF. Su descubridor es Frank Norman Wilson. En realidad, estas derivaciones se ubican en las mismas posiciones que las Derivaciones I, II y III, sólo que Wilson analizó la Ley de Einthoven y vio que combinando dos polos negativos, realzaba la actividad eléctrica que no se nota en las Derivaciones I, II y III.

Fórmulas de ECG de Wilson

Fórmulas de ECG de Wilson

¡¡Esto es fantástico!! En serio… lo es… significa que nuevamente usando las Leyes de Kirchhoff podemos obtener más derivaciones, en este caso la aVR, aVL y la aVF. ¿Y eso que quiere decir? Que si bien necesitamos 4 a 6 electrodos para recoger la señal… en la teoría nos basta con sólo 2 señales. I y II o I y III. Luego de acuerdo a la Ley de Einthoven y a las Fórmulas de Wilson, podemos obtener la derivación que falta. Luego podemos usar esa derivación faltante, para calcular las 3 extras. El resultado es que nuestro equipo es más fácil de conducir y sólo hace falta un cable de micrófono para introducir la señal. El resto es cosa de matemáticas.

De nuevo, me dirá alguno que no es lo mismo calcularlas que estimarlas. Insisto con que mi Proyecto de Tesis no se trata de construir un ECG 100% fiable que pase todas las pruebas que se exigen a estos equipos, sino que se trata de construir un equipo capaz de ayudar al especialista y que al ser más software que Hardware, pueda ser utilizado en cualquier PC con una tarjeta de sonido. Con eso a mí me basta. Dejémosle los ECG precisos al milímetro a Philips, a Siemens y demás fabricantes de equipo biomédico.

Naturalmente, no estoy considerando las derivaciones V1, V2, V3, V4, V5 y V6. No las consideraremos de momento. No hasta que tenga más literatura sobre ECG que pueda leer. De nuevo agradezco a Google Books.

Seguimos entonces. Como ya hemos dicho, tenemos que demostrar que efectivamente hacer lo que dice la teoría sea verdad… podamos derivar 6 derivaciones de sólo 2. Entonces, tenemos que buscar algún ECG hecho y derecho con todas sus derivaciones, tomar dos y tratar de crear las demás desde ellas. Esto parece un trabajo para… PhysioBank, una gran colección de base de datos de señales biomédicas para investigación y desarrollo de Software Libre.

Usaremos la base de datos llamada PTB Diagnostic DataBase, una base de datos de ECGs de 12 derivaciones, cortesía del Physikalisch-Technische Bundesanstalt (PTB) (Instituto Nacional de Metrología Alemán) y del Dr. Michael Oeff de la Clínica Universitaria Benjamín Franklin, en Berlín. Nos descargamos la versión en .mat o .csv de un paciente usando la interfaz de ATM de PhysioBank. El archivo debe incluir información de las 12 derivaciones y de dos detalles más, que no nos interesan a nosotros de momento.

Ejemplo de ECG de la PTB Database

Ejemplo de ECG de la PTB Database

De cualquier modo, usando la interfaz ATM de PhysioBank podemos ver las señales y separarlas. De esa interfaz podremos bajar un máximo de 10 segundos de datos de ECG. Si queremos más, bajaremos el archivo .dat que corresponden a esa lectura, pero de momento sólo queremos demostrar algo, así que no es realmente necesario. Con los 10 segundos bastan.

¿Y ahora con qué analizamos el .mat que nos acabamos de bajar? Esto es un trabajo… para Matlab. También podemos usar GNU Octave, pero en la Universidad, lo que tengo más a la mano es Matlab. Es una pena que la Universidad use más software propietario, aunque reconozco que Matlab es una herramienta muy, pero muy poderosa.

¿Qué es una señal? Para la máquina es un conjunto de valores expresados en un arreglo a lo largo del tiempo. Para los cables, naturalmente es un flujo de electrones que siguen cierto patrón. Pero quedémonos con la aproximación de un arreglo. ¿Qué podemos hacer con un arregl0? Sumarlo, restarlo, dividirlo, multiplicarlo, etc. Son números… podemos hacer todo cuanto queramos. Por ejemplo, aplicar la Ley de Einthoven y las Fórmulas de Wilson.

¿Y cómo sabemos si está bien? ¿Cómo sabemos si la señal reconstruida es equivalente a las que captó el equipo de ECG? Porque si no se parecen en nada, es mejor no usarlas, ya que podríamos hacerle problema al experto en vez de ayudalro. Para eso, es hora de buscar los libros de la Escuela Pre Universitaria y recordar un concepto… Desviación Estándar.

¿Y qué es la Desviación Estándar? Es básicamente la distancia promedio que hay entre todos los valores de un grupo de datos con su media aritmética. El asunto es que la Desviación Estándar se usa como medida de incertidumbre. Si tenemos dos grupo de datos y su desviación estándar es muy similar, podemos decir que estos datos son lo más cercanos posibles. Una diferencia entre la desviación estándar de dos grupos de datos que sea demasiado grande nos hará ver que esos valores son muy distintos y no pueden ser equivalentes ni similares. El plan es comparar los grupos de datos generados por algoritmos y los originales del ECG de ejemplo para ver si hay grandes diferencias en su desviación estándar. Si las hay… sabremos que esto de derivar todas las derivaciones es una mala idea.

(Actualización 02 – 06 – 2010: Lamentablemente la Desviación Estándar no es la mejor forma de ver si dos señales son muy similares. Mis asesores me recomendaron algo más exacto como la Prueba T Student, ya que la Desviación Estándar puede identificar como “similares” datos muy abismales si su diferencia entre sus propios elementos  similar.)

Bueno, primero nos bajamos el archivo .mat de uno de los ejemplos de la PTB Database. En mi caso, he bajado el archivo que dice ‘ptbdb/patient001/s0010_re.mat’. Pueden ubicarlo en la interfaz de ATM, ya que PhysioBank no permite el enlace directo.

Bueno, según el sitio de la PTB Database, estos son los detalles técnicos que hay que conocer:

  • 15 canales de datos (12 del ECG y los otros tres de ECG adicional, pero referente a V1, V2, V3, V4 y V6)
  • Frecuencia de muestreo de 1 Khz  (1000 Hz), lo que indica una sensibilidad de 0.001 segundos.
  • Resolución de 16 bits.

Bueno, el orden de las derivaciones en el archivo es: I, II, III, aVR, aVL, aVF, V1, V2, V3, V4, V5, V6, VX, VY y VZ. Los últimos 3 corresponden a algo llamado “Frank Leads ECG”, pero no he encontrado nada especial, así que supongo que serán derivaciones experimentales. No las consideraremos en nuestro trabajo al igual que de momento las 6 derivaciones V1, V2, V3, V4, V5 y V6.

Entonces en Matlab, cargamos el archivo .mat usando la sentencia ‘load‘. Dado que este no es un curso de Matlab, les copio y pego el código que use:

%%cargamos el archivo ecg_raw.mat
load 'ecg_raw.mat'
ecg_raw = val;
clear val;

%el archivo tiene las derivaciones en orden: i, ii, iii, avr, avl, avf,
%v1, v2, v3, v4, v5, v6

der1 = ecg_raw(1,:);
der2 = ecg_raw(2,:);
der3 = ecg_raw(3,:);

%ya tenemos las tres derivaciones, comprobamos si el ECG esta en orden....

der2_tmp = der1 + der3;

if (abs(std(der2) - std(der2_tmp)) < 1.0) %%Si el error es mas de 1.0 es que no coinciden
  disp('El ECG se conecto sin errores')
else
  disp('El ECG tiene errores')
end

disp(['Dev Est II: ', num2str(std(der2))]);
disp(['Dev Est IIa: ', num2str(std(der2_tmp))])
efact = std(der2) - std(der2_tmp);
efact = abs(efact);

%% efact * std(der2) / 100 -> porcentaje error
perr = (efact * std(der2)) / 100;
disp(['Porcentaje de error:', num2str(perr), '%']);

Bueno, hasta aquí hemos recogido en variables las derivaciones I, II y III. Acto seguido hemos calculado la Derivacion II usando la Ley de Einthoven y hemos calculado la derivación estándar de la Derivación II original y la Derivación II algorítmica. Acto seguido, tomo la derivación estándar de ambas y las resto, la Derivación II contra la II algoritmica. Luego, saco un porcentaje de ese numero con respecto a la Desviación Estándar de la Derivación II original. En mi caso, el resultado mostrado es el siguiente:

El ECG se conecto sin errores
Dev Est II: 255.6288
Dev Est IIa: 255.6361
Porcentaje de error:0.018641%

Tenemos un porcentaje de error de 0.018641% con respecto a la Derivación II original. Es decir… el error no es nisiquiera del 1%. Es suficiente para nuestros propósitos. Si queremos verlo, sencillamente escribiremos: ‘plot(der2)’ y luego ‘plot(der2_tmp)’, para ver la Derivación II original y algorítmica. Se deberían notar igual.

(Actualización 02 – 06 – 2010: La Desviación Estándar no es la forma correcta de hacer esta medición. Se usa la Prueba T Student. Colgaré otro post a la brevedad con las correcciones del caso)

Ya hemos visto que la Ley de Einthoven se cumple. Ahora, vamos por las derivaciones auxiliares: aVR, aVF y aVL. Pero antes, verán que hay un condicional que dice que el ECG se conectó sin errores. Es que la Ley de Einthoven se usa para autodiagnóstico. El equipo de ECG puede decirnos si los electrodos están bien colocados si se cumple. Así que es posible que al final, leamos las 3 derivaciones, porque si no, no podremos saber si las tomas se han colocado como debe de ser. Este requerimiento dependerá de mi asesor de Tesis, no de mí.

Ahora sí, veamos las otras derivaciones:

avr_a = ((der1 + der2) / 2) * -1;
avf_a = der2 - (der1 / 2);
avl_a = der1 - (der2 / 2);
%calculamos la deriv. estandar y comprobamos contra las oficiales
avr = ecg_raw(4,:);
avl = ecg_raw(5,:);
avf = ecg_raw(6,:);
disp(['Dev Est aVR: ', num2str(std(avr))]);
disp(['Dev Est aVRa: ', num2str(std(avr_a))])
disp(['Dev Est aVL: ', num2str(std(avl))]);
disp(['Dev Est aVLa: ', num2str(std(avl_a))])
disp(['Dev Est aVF: ', num2str(std(avf))]);
disp(['Dev Est aVFa: ', num2str(std(avf_a))])

Aqui no hay nada que decir, salvo que calculamos las derivaciones aVR, aVF y aVL. Y mostramos la derivación estándar de cada una, tanto la original que viene con el ECG y la algorítmica. En mi caso, esto es lo que muestra el Matlab:

Dev Est aVR: 185.701
Dev Est aVRa: 185.7917
Dev Est aVL: 306.3242
Dev Est aVLa: 306.3249
Dev Est aVF: 293.1127
Dev Est aVFa: 293.1097

Decir que la ‘a’ minúscula al final de las derivaciones indica que es la calculada algorítmicamente. Como podemos ver, la diferencia entre desviaciones estándar es por centésimas. Es decir, el error es menor del 1%. Suficiente para propósitos académicos. Para propósitos médicos cre0 que no se hace tan a la ligera. Otra cosa que deberé debatir con mi asesor… pero de momento, estamos bien, matemáticamente hablando, claro.

Naturalmente, para los fans de GNU Octave esto se puede hacer en Octave igual. Lamentablemente la Universidad tiene Matlab y esto lo hago en horas de clases. Así que futuros artículos seguirán con Matlab. Cuando encuentre un tiempo tal vez lo pase a Scilab, Octave o Python inclusive. De momento por tiempo, a mi me importa prototipar enseguida, y Matlab hace muy buen trabajo en estos casos.

Finalmente decir que no soy perfecto y que mi formación matemática no es la mejor de todas, así que si cometo un error o algo, me gustaría que me lo digan para corregirme. Este Proyecto de Tesis es para todos los lectores y tengo la intención de hacerlo público, incluído el software. Pero para eso, necesito su apoyo y su feedback para corregir alguno que otro error. Seguiremos aquí después de que exponga el primer avance de Tesis I.

Posted in Opinion, Papers, Personal, Programacion, Tesis | Comentarios desactivados en Proyecto de Tesis de ECG – Parte 1.5

Proyecto de Tesis de ECG – Parte 1

Posted by brunoprog64 en mayo 4, 2010

Ante todo, de nuevo me disculpo a mis lectores por la inactividad. Cada vez me es más difícil poder escribir en el blog, por tiempo y responsabilidades.

Habíamos dicho que andaba buscando un tema de tesis. Después de recibir una noticia con respecto a un conocido que viene de intercambio con un tema innovador, no me quiero quedar atrás y me ratifico escogiendo el Proyecto de ECG como mi tema de tesis. Esta serie de post van a tratar de como voy desarrollando este proyecto. De ahí a que he creado una nueva categoría: Tesis.

Antes de seguir y dado que esto es como el diario de mi tesis, expliquemos porqué escogí un tema así. Después de todo hay temas más facilones… o más interesantes. Expliquémosnos.

Dos indicadores a mi parecer, muy importantes, en los procesos de ánimo son tanto el corazón y el cerebro. El pulso y la presión arterial se vuelven indicadores de múltiples estados anímicos. Así pues, el pulso nos subirá si nos asustamos o nos emocionamos, pero creo que cuando tenemos miedo nos baja la presión y cuando nos emocionamos nos sube. En el cerebro debe haber un aumento de ciertas ondas del estado cerebral, pero desconozco detalles exactos.  Es decir… con un monitoreo constante de las señales del corazón podemos tener una idea de nuestro estado de ánimo… esto es útil para videojuegos o sistemas de enseñanza.

De cualquier modo, un dispositivo de monitoreo ambulatorio sería muy deseable en estos casos. De todos modos, estos dispositivos son caros, así que es difícil acceder a ellos. ¿Porqué entonces no diseñamos uno? ¿Acaso un ECG puede ser tan complicado? Pues este post del blog SWHarden nos muestra que un ECG no es tan caro ni difícil como imaginamos.

Actualmente mi proyecto está en etapa de recopilar datos, así que salvo un documento inútil que voy a enlazar más adelante, hoy hablaremos de teoría. Agradesco al blog SW Harden por algunas cosas, pero en especial al libro “Understanding Electrocardiography” y a su edición de bolsillo (Mi universidad sólo tiene la de bolsillo) de Mary Boudreau Conover, porque explican el tema eléctrico de manera accesible a un profano como yo.

Monitor de ECG

Monitor de ECG

En lo que yo he visto, hay dos tipos de Monitores de ECG: El monitor de papel y el monitor digital. El problema, es que el monitor digital monitorisa otras cosas además que el ECG propiamente dicho: Pulso, tensión, saturación, temperatura, etc.

He podido encontrar información detallada sólo sobre como medir la saturación. No he conseguido detalles sobre como medir la presión y demás, así que de momento lo dejamos en un monitor de ECG que muestre pulso y de ser posible saturación.

Ahora vamos a mencionar que en el tema de electrodos para ECG tenemos 3 tipos:

  • Electrodos bipolares
  • Electrodos unipolares
  • Electrodos adicionales

Típicamente, el sistema de ECG es uno de 12 canales, donde se distingen las siguientes derivaciones:

  • Derivaciones I, II y III.
  • Derivaciones aVR, aVL, aVF.
  • Derivaciones V1, V2, V3, V4, V5 y V6.

Explico a detalle de que estoy hablando. El corazón es un músculo eléctrico, por lo tanto registraremos una señal diferente con respecto a donde coloquemos los electrodos. Cada una de esas “señales” es una derivación, un “ángulo” eléctrico mediante el cual veremos el corazón.

Sobre lo de bipolares, unipolares y adicionales, me refiero a que hay derivaciones en las que recogemos señal tanto positiva y negativa (+, -), por lo que precisamos de dos electrodos para recoger la señal, estas son las bipolares. Otras en las que sólo basta un electrodo para recoger la señal, son las unipolares. Finalmente las adicionales no son 3 electrodos más, sino que son una permutación entre el positivo y negativo de las bipolares para sacar mas datos.

Triángulo de Einthoven

Triángulo de Einthoven

Una forma más simple de explicar todo este asunto es mediante el Triángulo de Einthoven, que está al lado de este texto. Para visualizar el triángulo, que una persona se ponga firme y extienda los brazos. Entonces, si colocamos un electrodo en el brazo izquierdo, otro en el derecho y un tercero en su pierna izquierda, tendremos un triángulo ficticio que indica el recorrido de la actividad eléctrica del corazón. con esto podemos saber cual derivación es cual.

– Derivación I: El electrodo en el brazo derecho es el negativo y el electrodo en el brazo izquierdo es positivo.

– Derivación II: El electrodo en el brazo derecho es negativo y el electrodo en la pierna izquierda es positivo.

– Derivación III: El electrodo en el brazo izquierdo es negativo y el electrodo en la pierna izquierda es positivo.

– Derivación aVR: Electrodo positivo en el brazo derecho y el electrodo negativo es la unión de la pierna y brazo izquierdos.

– Derivación aVL: Electrodo positivo en el brazo izquierdo y el electrodo negativo es la unión de la pierna izquierda y brazo derecho.

– Derivación aVF: Electrodo positivo en la pierna izquierda y electrodo negativo es la unión de los brazos izquierdo y derecho.

Las derivaciones de V1 a V6 son unipolares porque están muy cerca del corazón.

Esto ya nos hace ver que la construcción de un ECG no es tan simple, ya que debemos encontrar un método de como cambiar la polarización a cada momento. Esta señal debe amplificarse, por lo que dispondremos de un Amplificador Operacional. Estos suelen aceptar señal positiva y negativa. Conectaremos cada uno de una forma en especial para dar con la derivación que deseamos. En mi caso es muy probable que mi trabajo sólo se centre en el Triángulo de Einthoven, ya que sólo sería necesario…. 3 0 4 derivaciones. Hay formas “algorítmicas” de calcular aVR, aVL y aVF dado que el Triángulo de Einthoven sigue las Leyes de Kirchhoff, pero de momento no nos compliquemos más. En aras a la sencillez, pensaré de momento en las tres derivaciones básicas: I, II y III. En cuando tenga acceso a más bibliografía hablaremos de las demás derivaciones.

Entonces lo ideal sería… encontrar un método para capturar estas señales. SW Harden y su blog nos dicen que podemos usar el micrófono de una PC para llevar la señal… sólo que hay un problema: Los micrófonos registran sólo dos canales de audio: L y R, y el corazón en el modo mas básico tiene 3 canales. Así que deberíamos diseñar un equipo que permita multiplexar señal hacia la tarjeta de sonido para poder ver las 3 posibles derivaciones. El problema es que introducimos delay en el registro de ECG.

El estándar de ECG en papel dice que los papeles usados para graficar el ECG tiene cuadritos de 4 mm. La velocidad promedio es del papel es de 25 mm/s, por lo que cada cuadrito reperesnta 0.04 segundos de ECG.

Explico mejor lo del “delay”, que decia antes. Es deseable introducir la señal del ECG por la tarjeta de sonido, porque podemos tratarla como si fuera señal de audio. Y así podemos amplificarla, filtrarla, tratarla y recogerla con más facilidad, sólo hay que pretender que es un audio. La otra opción seria entrar la señal por puerto serial o USB, pero ahí tendríamos que manejar todo el procesado y filtrado a mano. Después de todo la tarjeta de sonido es un gran convertidor ADC (Analógico-Digital) y hay que aprovecharlo. Ya dijimos que el problema está en que los micrófonos normales sólo dejan entrar dos canales de audio: L y R y que el corazón tiene 3 canales de señales según el Triángulo de Einthoven.

Entonces si sabemos que el estándar de ECG es de papel a cuadros es de 25 mm/s y que cada cuadro normado representa o.o4 segundos de ECG, entonces veremos que no hay necesidad de muestrear a… 0.08 segundos de ECG… porque sólo nos interesa que la velocidad sea de 0.04 segundos. Si la PC es más veloz, podríamos usar ese tiempo extra en cambiar la polaridad de las señales (Considerando a L como positivo y R como negativo) entre los electrodos I, II y III para con sólo un cable estéreo tener las tres derivaciones.

Multiplexado por División de Frecuencia

Multiplexado por División de Frecuencia

(Nota del Autor: Sin embargo la idea no la tengo del todo clara, agradezo que me den ideas al respecto)

Según este paper, la base de datos de arritmias del MIT-BIH está digitalizda a 11 bits con 360 Hz de velocidad de muestreo. Dado que nosotros queremos leer 3 señales diferentes, hay que aumentar un poco más la velocidad de muestreo. 360 * 3 = 1080 Hz de velocidad de muestreo. Sólo debemos instruir a nuestro software que de 1 segundo de señal, 1/3 sea para cada derivación. Naturalmente que al hacer esto multiplexando, perderemos valores, pero como hacemos muestreo tan alto, se puede compensar. Agradesco si me aclaran un poco este detalle.

Otra solución sería usar multiplexacion por división de frecuencias. Los ECG tienen una frecuencia determinada, por lo que las “subimos” un poco y enviamos por el cable todo ese mix, luego por software demultiplexamos y analizamos la señal. De igual modo, yo no soy experto en telecomunicaciones, así que corríganme si digo tonterías.

Finalmente, en el curso de Tesis I nos piden un pequeño documento describiendo nuestra idea. Aquí cuelgo el que presenté para los interesados. Volveré a postear cuando tenga más avances para ustedes. De momento decir que ya que estudio Ingeniería de Sistemas, mi docente no aceptará el tema electrponico o pedirá que lo delegue. De todos modos de algo me informo no vaya a ser que me timen… porque suele pasar.

Posted in Opinion, Papers, Personal, Programacion, Tesis | Comentarios desactivados en Proyecto de Tesis de ECG – Parte 1