diff --git "a/IMPETOM-Cl\303\255nico/Arduino.py" "b/IMPETOM-Cl\303\255nico/Arduino.py" deleted file mode 100644 index 595e07c88dcb2eac52397e421bf8872b96dd20c4..0000000000000000000000000000000000000000 --- "a/IMPETOM-Cl\303\255nico/Arduino.py" +++ /dev/null @@ -1,188 +0,0 @@ -import time - -import numpy as np -import serial -import serial.tools.list_ports -import array as arr -from ImpetomCError import ImpetomCError -from Archivos import Archivos - -class Arduino: - """ - Esta clase permite la creación y manejo del objeto Arduino. - - """ - - - def __init__(self,baudrate, timeout,vThreshold): - """ - Método constructor para la clase Arduino. Permite la creación del objeto arduino. En caso de existir un Arduino conectado a la PC, lo detecta y guarda en este objeto el puerto COM y abre el canal serial. - - :param baudrate: Es la frecuencia del canal serial - :param timeout: Es el valor máximo de tiempo antes de que el canal se cierre sin que se haya recibido ningun dato. Se recomienda no poner timeout menor a 0.1 ya que si no da la conexión da problemas. - :param vThreshold: Es el valor de voltaje a partir del cual se considera que el electrodo esta mal conectado (debe ser un float) - - :exception ImpetomCError: Devuelve una excepción indicando que no se detecto ningun arduino conectado a la pc - """ - - self.puerto = self.__buscarPuertoCom() - self.baudrate = baudrate - self.modo = 0 # Modo Setup por defecto, modo Reconstrucción = 1 - self.timeout = timeout - self.frecuenciaDDS = "30000" - self.ard = serial.Serial(port=self.puerto,baudrate=self.baudrate,timeout=self.timeout) - self.vThreshold = vThreshold - self.__establecerComunicacion() - self.modoColocacionPares = False - self.datos = np.zeros(208) - - - def __buscarPuertoCom(self): - """ - Esta función permite buscar al arduino dentro de los puertos COM conectados al PC - - :exception ImpetomCError: Tira un error en caso de no encontrar ningún arduino conectado al sistema - - """ - - ports = list(serial.tools.list_ports.comports()) - ArduinoPort = '' - - for p in ports: - if "CH340" in p.description or "USB" in p.description or "COM3" in p.description:# Windows reconoce asà al arduino - ArduinoPort = p.name - if ArduinoPort == '': - raise ImpetomCError ("Error: No se encontró ningún dispositivo Arduino conectado.") - - else: - return ArduinoPort - - - def __establecerComunicacion (self): - """ - Esta función establece la comunicación entre la pc y el arduino de impetomC. - - :exception ImpetomCError: Devuelve una excepción indicando que el Arduino conectado no es el arduino de Impetom ClÃnico. - """ - - data = "" - intento = 0 - while data == "" and intento < 20: - self.ard.write(bytes("1", 'utf-8')) - time.sleep(0.05) - data = self.ard.readline().decode('utf-8').rstrip() - intento += 1 - if intento == 20 or data != "ImpetomC": - raise ImpetomCError("Error: No se encontró el dispositivo de ImpetomC.") - time.sleep(0.05) - - - def obtenerMedidas(self): - """ - Esta función obtiene las 208 medidas de tensión realizadas por el arduino ImpetomC para la reconstrucción tomográfica. - - :returns: **datos** - Devuelve el vector con las 208 medidas realizadas. - - **voltajesElevados** - Devuelve la cantidad de voltajes por encima de vThreshold. - - **frecuenciaArd** - Retorna el valor de la frecuencia a la que esta operando el dispositivo Impetom. - - **voltajesElevadosSeguidos** - Retorna la cantidad de voltajes elevados consecutivos (> vThreshold) que fueron detectados. Este dato se utiliza para verificar si hay electrodos desconectados en el dispositivo fÃsico. - - **tiraMedidaElevada** - Retorna el valor del electrodo que se detectó esta desconectado en el dispositivo fÃsico. - - :exception ImpetomCError: En caso de que el Arduino ImpetomC se haya desconectado durante la adquisición de datos devuelve una excepción. - """ - - modo = str(self.modo) - try: - self.ard.write(bytes(modo, 'utf-8'))# Indico al Arduino ImpetomC en que modo debe operar (0 - Setup ; 1 - Reconstrucción) - self.ard.write(bytes(self.frecuenciaDDS,'utf-8')) # Indico al Arduino ImpetomC a que frecuencia debe operar - i=0 - j=0 - tiraMedida = 0 - tiraMedidaElevada = np.zeros(16) - ele_seguidos=0 - voltajesElevadosSeguidos=0 - voltajesElevados=0 - while i < 208: - data = self.ard.readline().decode('utf-8').rstrip() - if data != "": # Esto es para asegurarme que cada vez que le pido un dato al equipo, lo recibo sin problemas. A veces sucede que no da la velocidad del canal - num = float(int(data) * 5 / 1023) - self.datos[i]= num - i += 1 - if i % 13 == 0: # Cada par de electrodos de corriente tiene 13 medidas de tensión asosciadas, con esto identifico los electrodos de corriente - tiraMedida += 1 - if num > self.vThreshold : - ele_seguidos +=1 - voltajesElevados += 1 - voltajesElevadosSeguidos = max(voltajesElevadosSeguidos, ele_seguidos) - if ele_seguidos % 13 == 0: # Registro tira de 13 voltajes elevados - if j<16 and tiraMedidaElevada[j] != tiraMedida: - tiraMedidaElevada[j] = tiraMedida - j += 1 - else: ele_seguidos = 0 - frecuenciaArd = self.ard.readline().decode('utf-8').rstrip() - except serial.SerialException:#Manejo del error de si el dispositivo se desconecta durante la adquisición de datos - raise ImpetomCError("El Hardware se desconectó durante la adquisición.") - self.datos=np.float32(self.datos) - return [self.datos,voltajesElevados,frecuenciaArd,voltajesElevadosSeguidos,tiraMedidaElevada] - - - def cambiarModoDeOperacion(self,mode): - """ - Esta función permite realizar el cambio de modo del Arduino ImpetomC. - - :param mode: String que debe indicar : "Reconstrucción" o "Setup". - - :exception ImpetomCError: Tira una excepción en caso de que mode sea distinto a los valores aceptados. - """ - - if (mode == "Reconstruccion"): - self.modo = 1 - elif (mode == "Setup"): - self.modo = 0 - else: - raise ImpetomCError("Error: Modo de operación incorrecto. Debe ser \"Reconstruccion\" o \"Setup\"") - - def cambiarFrecuenciaDDS(self,frecuenciaDDS): - """ - Función que permite cambiar el valor de la frecuencia del DDS del dispositvo ImpetomC. - - :param frecuenciaDDS: Valor de la nueva frecuencia del DDS. - - """ - - if(type(frecuenciaDDS) != str): - raise ImpetomCError("Error: La frecuencia del DDS debe estar en formato String") - self.frecuenciaDDS=str(frecuenciaDDS) - - def abrirPuertoSerie(self): - """ - Permite abrir el puerto serie. - Por defecto cuando se crea el objeto el puerto queda abierto, por lo que solo se debe usar si el puerto se - cerró en algun momento. - - :except ImpetomCError: En caso de utilizarse con el puerto ya abierto devuelve una excepción. - """ - - try: - self.ard.open() - self.__establecerComunicacion() - except serial.SerialException as se: # En caso de que se haya desconectado el dispositivo - if (str(se) == "El puerto ya está siendo utilizado"): # En caso de que el puerto ya esté abierto - raise ImpetomCError(str(se)) - else: # En caso de que el error sea por una desconexión - self.puerto=self.__buscarPuertoCom() - self.ard = serial.Serial(port=self.puerto,baudrate=self.baudrate,timeout=self.timeout) - self.__establecerComunicacion() - - - - def cerrarPuertoSerie(self): - """ - Permite cerrar el puerto serie. - """ - - self.ard.close() - diff --git "a/IMPETOM-Cl\303\255nico/ImpetomC.py" "b/IMPETOM-Cl\303\255nico/ImpetomC.py" deleted file mode 100644 index 4d7873cd56f4cfc64465fd998e98c1339a13bea8..0000000000000000000000000000000000000000 --- "a/IMPETOM-Cl\303\255nico/ImpetomC.py" +++ /dev/null @@ -1,394 +0,0 @@ -import threading -import time -from datetime import date, datetime -import numpy as np -import re -from pyeit.eit import jac -from pyeit.eit.interp2d import sim2pts - -from Archivos import Archivos -from Arduino import Arduino -from ImagenesDicom import ImagenesDicom -import os -from ImpetomCError import ImpetomCError -from ImpetomCElectrodeError import ImpetomCElectrodeError -import matplotlib.pyplot as plt - -#modulos de pyeit -import pyeit.mesh as mesh -from pyeit.eit.fem import Forward -from pyeit.eit.utils import eit_scan_lines -from pyeit.mesh.shape import thorax,circle - -flag_InstanceStudy = True - -class ImpetomC: - """ - Permite manejar todas las funcionalidades de la aplicación ImpetomC - - - Generación y guardado de la imagen tomográfica en formato dicom - - Conexión del arduino ImpetomC al puerto serie - - """ - - #Parametros para las imagenes reconstruidas - cmap=plt.cm.RdYlBu # color para las imagenes generadas - shape = "thorax" - lamb=0.01 - - #vectores de datos - datos = np.zeros(208) # Variable para el manejo de los datos de entrada desde Arduino ImpetomC - archiVH = Archivos("homo_py.txt")# vector homogéneo por defecto. Puede cambiarse utilizando la función actualizarVectorDeDatosHomogeneo - vHomogeneo = archiVH.leerArchivo() - - #Variables para el manejo del dispositivo ImpetomC - ard = None # se actualiza con startUp() o __arduinoConnect() - arduinoComunicationError = None # Variable para manejar el error de que se desconecte el Arduino de la pc mientras adquiere datos - - # Variables globales utilizadas para el manejo de problemas asosciados a los electrodos - voltajesElevados = 0 - voltajesElevadosSeguidos = 0 - tiraMedidaElevada = 0 - - #Parámetros del sistema - rootDir=os.path.dirname(os.path.abspath("ImpetomC.py")).replace("ImpetomC.py","") #Ubicación del directorio donde se guardaran las imágenes generadas - today = date.today().strftime("%b-%d-%Y") - - #Establecimiento de los parámetros de la imagen dicom - imgDicom = ImagenesDicom(p=0.3,lamb=lamb,file_path_jpg= os.path.join(rootDir, "IMG.jpg"),today=today,rootDir=rootDir, shape=shape) - - - @classmethod - def startUp(cls): - """ - Esta función permite hacer el start up de la aplicación. Utilizarla para dar inicio a la aplicación - - :exception ImpetomCError: Devuelve una excepción en caso de encontrar problemas con la conexión a el dispositivo Arduino - """ - - cls.__arduinoConnect() - - @classmethod - def __arduinoConnect(cls): - """ - Permite establecer la conexión con el Arduino con el software de ImpetomC - - :exception ImpetomCError: Devuelve una excepción con el mensaje correspondiente - """ - - cls.ard = Arduino(baudrate = 9600, timeout = 0.1,vThreshold = 4.0) #para cambiar el valor del threshold de voltaje cambiar vThreshold - cls.arduinoComunicationError = None - - - @classmethod - def reset(cls): - """ - Este método permite realizar el reseteo de la aplicacion, devolviendo la aplicacion a sus valores por defecto - """ - - cls.datos = np.zeros(208) - cls.ard.cerrarPuertoSerie() - archiVH = Archivos("homo_py.txt") # vector homogéneo por defecto. Puede cambiarse utilizando la función actualizarVectorDeDatosHomogeneo - cls.vHomogeneo = archiVH.leerArchivo() - cls.startUp() - - @classmethod - def actualizarVectorDeDatosHomogeneo(cls): - """ - Permite volver a cargar el vector de datos homogeneo en modo reconstrucción para un mejor detalle del vector - """ - - cls.ard.cambiarModoDeOperacion("Reconstruccion") - datosRecalibrados, ve, fa, vS, ta = cls.ard.obtenerMedidas() - archiCalibrar = Archivos("datos_calibrar.txt") - archiCalibrar.escribirArchivo(datosRecalibrados) - cls.vHomogeneo = archiCalibrar.leerArchivo() - - - @classmethod - def __verificarParametrosParaImagen(cls,mode,shape,vmax,vmin,screenWidth,p,sclEnable): - """ - Permite verificar que los parámetros de entrada para la reconstrucción tomográfica sean correctos - - :param mode: Tipo string, debe contener la palabra "reconstruccion" o "setup" - :param shape: Tipo String, debe contener la palabra "thorax" o "circle" - :param vmax: Tipo float, máximo valor para la escala de la imagen - :param vmin: Tipo float, mÃnimo valor para la escala de la imagen - :param screenWidth: Tipo Int, ancho de la pantalla del usuario - :param p: Parámetro para la reconstrucción con JAC, se recomienda que el valor esté en 0.1 y 0.9 - :param SclEnable: Debe ser un booleano. True para utilizar los valores vmax y vmin y false para no utilizarlos - - :returns: **meshDensity** - Retorna la densidad de mesh a utilizar, esto depende de el modo de trabajo de la aplicación y el shape utilizado - - **retShape** - Retorna un shape reconocible por las funcionalidades de pyEIT - - :exception ImpetomCError: Devuelve una excepción con el mensaje de error correspondiente - """ - - mode=mode.lower() - if mode == "reconstruccion": # Determino el mesh density - meshDensity= 0.045 - elif mode == "setup": - if shape == "thorax": # Determino mesh de setup según modelo - meshDensity = 0.07 - - elif shape == "circle": - meshDensity = 0.1 - else: - raise ImpetomCError("Forma para la reconstrucción inválida, debe ser \"Thorax\" o \"Circle\"") - else: - raise ImpetomCError("Modo de reconstrucción inválido. Debe ser \"Reconstruccion\" o \"Setup\"") - - shape=shape.lower() - if shape == "thorax": # Determino la forma de la reconstrucción - retShape=thorax - - elif shape == "circle": - retShape = circle - - else: - raise ImpetomCError("Forma para la reconstrucción inválida, debe ser \"Thorax\" o \"Circle\"") - - if type(vmax) != float or type(vmin) != float or type(screenWidth) != int or type(p) != float or type(sclEnable) != bool: - raise ImpetomCError("vmax, vmin, p deben ser floats , screenWidth debe ser un int y sclEnable un bool") - elif screenWidth <= 0 or p <=0 : - raise ImpetomCError("screenWidth y p deben ser mayores que 0") - return [meshDensity,retShape] - - @classmethod - def __obtenerimagen(cls,vectorDatos,SclEnable,vmax,vmin,shape,mode,p,screenWidth): - """ - Pemite generar una imágen tomográfica a partir de un vector de datos, entre otros parámetros - - :param vectorDatos: Vector de 208 valores de tensión para reconstruir la imágen tomográfica - :param SclEnable: Debe ser un booleano. True para utilizar los valores vmax y vmin y false para no utilizarlos - :param vmax: Máximo valor para la escala de la imagen - :param vmin: MÃnimo valor para la escala de la imagen - :param shape: Forma de la reconstrucción "thorax" o "circle" - :param mode: Modo en el que fueron tomadas las medidas de vectorDatos ("reconstruccion" o "setup") - :param p: Parámetro para la reconstrucción con JAC, se recomienda que el valor esté entre 0.1 y 0.9 - :param screenWidth: Ancho de la pantalla del usuario - - :exception ImpetomCError: Devuelve una excepción con el mensaje de error correspondiente - """ - - meshDensity, correctShape = cls.__verificarParametrosParaImagen(sclEnable=SclEnable,vmax=vmax,vmin=vmin,shape=shape,mode=mode,p=p,screenWidth=screenWidth) - mesh_obj, el_pos = mesh.create(16, h0=meshDensity, fd=correctShape) - pts = mesh_obj["node"] - tri = mesh_obj["element"] - x, y = pts[:, 0], pts[:, 1] - - if shape == "circle": - el_pos = el_pos + 12 # Electrodo 1 en las "6" del reloj - for i in range(4, 16): - el_pos[i] = el_pos[i] - 16 - - el_dist, step = 1, 1 - ex_mat = eit_scan_lines(16, el_dist) - eit = jac.JAC(mesh_obj, el_pos, ex_mat=ex_mat, step=step, perm=1.0, parser="fmmu") - eit.setup(p=p, lamb=cls.lamb, method="kotre") - - ds_n = eit.solve(vectorDatos, cls.vHomogeneo, normalize=True) - ds = sim2pts(pts, tri, np.real(ds_n)) - - fig, ax = plt.subplots(1, 1, constrained_layout=True) - fig.set_size_inches(7, 5) - - if (SclEnable): - im = ax.tripcolor(x, y, tri, ds, shading="flat", cmap= cls.cmap, vmax=vmax, vmin=vmin) - else: - im = ax.tripcolor(x, y, tri, ds, shading="flat", cmap=cls.cmap) - - if shape == "thorax": # Electrodos Thorax - for i, e in enumerate(el_pos): - if i <= 4: - ax.annotate(str(i + 1), xy=(x[e] - 0.05, y[e] - 0.05), color="w") - elif i <= 7: - ax.annotate(str(i + 1), xy=(x[e] - 0.04, y[e]), color="w") - else: - if i <= 11: - ax.annotate(str(i + 1), xy=(x[e], y[e]), color="w") - else: - ax.annotate(str(i + 1), xy=(x[e], y[e] - 0.05), color="w") - elif shape == "circle": # Electrodos Circle - for i, e in enumerate(el_pos): - if 1 <= i <= 7: - if i <= 3: - ax.annotate(str(i + 1), xy=(x[e] - 0.05, y[e] - 0.05), color="w") - else: - ax.annotate(str(i + 1), xy=(x[e] - 0.05, y[e]), color="w") - elif i >= 14: - ax.annotate(str(i + 1), xy=(x[e] + 0.04, y[e] - 0.05), color="w") - elif i == 0: - ax.annotate(str(i + 1), xy=(x[e], y[e] - 0.05), color="w") - else: - ax.annotate(str(i + 1), xy=(x[e], y[e]), color="w") - - ax.axis("off") - cbar = fig.colorbar(im) - cbar_yticks = plt.getp(cbar.ax.axes, 'yticklabels') - plt.setp(cbar_yticks, color='w') - ax.set_aspect("equal") - fig.patch.set_facecolor('black') - fig.savefig('IMG.jpg', dpi=(100/1200)*screenWidth) - plt.close(fig) - - @classmethod - def generarImagenTomografica(cls,mode,shape,screenWidth,sclEnable,vmax,vmin,p,frecuenciaDDS): - """ - Permite generar la imagen tomográfica y la guarda en la raÃz del proyecto como IMG.jpg - - :param mode: Modo en el que debe operar el dispositivo ImpetomC - :param shape: Forma de la reconstrucción "thorax" o "circle" - :param screenWidth: Ancho de la pantalla del usuario - :param SclEnable: Debe ser un booleano. True para utilizar los valores vmax y vmin y false para no utilizarlos - :param vmax: Máximo valor para la escala de la imagen - :param vmin: MÃnimo valor para la escala de la imagen - :param p: Parámetro para la reconstrucción con JAC, se recomienda que el valor este en 0.1 y 0.9 - :param frecuenciaDDS: Valor de frecuencia a la que debera operar el DDS del dispositvo ImpetomC - - :exception ImpetomCElectrodeError: Devuelve una excepción con una mensaje que indica el problema detectado con los electrodos - :exception ImpetomCError: Devuelve una excepción con un mensaje de error por errores distintos al anterior - """ - - global voltajesElevados, voltajesElevadosSeguidos, tiraMedidaElevada - if(type(frecuenciaDDS) != str): - raise ImpetomCError("La frecuencia del dds debe ser un String") - if cls.datos[0] == 0: #Verifico si es la primera vez que se ejecuta la aplicación o si el dispositivo se desconectó - cls.__tomarMedidasParaImagen(mode, frecuenciaDDS) - threading.Thread(target=cls.__tomarMedidasParaImagen(mode,frecuenciaDDS)).start() - cls.__obtenerimagen(vectorDatos=cls.datos,screenWidth=screenWidth,SclEnable=sclEnable,vmax=vmax,vmin=vmin,p=p,shape=shape,mode=mode) - - if voltajesElevados >= 26 and voltajesElevadosSeguidos >= 13: - if tiraMedidaElevada[0] != 0: - imprimir_ele = [] - for dato in tiraMedidaElevada: - if dato != 0: - imprimir_ele.append(int(dato)) - raise ImpetomCElectrodeError("Se detectó un falso contacto en al menos un electrodo. Revise los electrodos " + str(imprimir_ele)) - elif voltajesElevados > 64: - raise ImpetomCElectrodeError("Se detectaron varios electrodos con tensiones elevadas, se recomienda regular la ganancia del dispositivo.",regularGanancia=True) - elif voltajesElevados <= 13: - raise ImpetomCElectrodeError("Se detectaron varios electrodos con tensiones bajas, se recomienda regular la ganancia del dispositivo.", regularGanancia=True) - elif cls.arduinoComunicationError == None: # verifico que no se haya desconectado el dispositivo durante la adquisición - threading.Thread(target=cls.__tomarMedidasParaImagen(mode,frecuenciaDDS)).start() - tiImagen=time.time() - cls.__obtenerimagen(vectorDatos=cls.datos,screenWidth=screenWidth,SclEnable=sclEnable,vmax=vmax,vmin=vmin,p=p,shape=shape,mode=mode) - tfImagen=time.time() - if voltajesElevados >= 26 and voltajesElevadosSeguidos >= 13: - if tiraMedidaElevada[0] != 0: - imprimir_ele = [] - for dato in tiraMedidaElevada: - if dato != 0: - imprimir_ele.append(int(dato)) - raise ImpetomCElectrodeError("Se detectó un falso contacto en al menos un electrodo. Revise los electrodos " + str(imprimir_ele)) - elif voltajesElevados > 64: - raise ImpetomCElectrodeError(msg="Se detectaron varios electrodos con tensiones elevadas, se recomienda regular la ganancia del dispositivo.",regularGanancia=True) - elif voltajesElevados <= 13: - raise ImpetomCElectrodeError(msg="Se detectaron varios electrodos con tensiones bajas, se recomienda regular la ganancia del dispositivo.",regularGanancia=True) - elif cls.arduinoComunicationError != None:# Si se desconectó el dispositivo durante la adquisición - cls.datos= np.zeros(208) #Reinicio el vector de datos - cls.ard.datos=np.zeros(208) - raise ImpetomCError(cls.arduinoComunicationError) - - @classmethod - def __tomarMedidasParaImagen(cls,mode,frecuenciaDDS): - """ - Utiliza al objeto arduino generado para comunicarse con este y obtener las medidas de tension necesarias para realizar la reconstruccion tomográfica del paciente. - Las medidas obtenidos son guardadas en la variable datos - - :param mode: Modo de operación para el dispositvo ImpetomC - :param frecuenciaDDS: Frecuencia de operación para el dispositvo DDS - - """ - - global arduinoComunicationError,voltajesElevados, voltajesElevadosSeguidos,tiraMedidaElevada - cls.ard.cambiarModoDeOperacion(mode) - cls.ard.cambiarFrecuenciaDDS(frecuenciaDDS) - try: - tidatos = time.time() - cls.datos,voltajesElevados,frecuenciaArd,voltajesElevadosSeguidos,tiraMedidaElevada= cls.ard.obtenerMedidas() - archi = Archivos("img.txt") - archi.escribirArchivo(cls.datos) - tfdatos = time.time() - cls.arduinoComunicationError = None - except ImpetomCError as e:# Escribo el msj de error en arduinoComunicationError - cls.arduinoComunicationError = str(e) - - @classmethod - def __verificarParametrosParaHistoriaClinica(cls,pacientName,pacientCi,p,birthDate,sex,medida,medidaZ,shape,mode): - """ - Permite verificar que los parámetros de entrada para la reconstrucción tomográfica sean correctos - - :parameter pacientName: Tipo string, no debe estar vacÃo - :param pacientCi: Tipo String, no debe estar vacÃo y ser una cadena de números - :param p: Tipo float, debe ser mayor que 0 - :param birthDate: Debe ser un String válido a convertir a fecha en el formato dd-mm-yyyy - :param sex: Tipo String, debe ser "M", "F" o "Otro" - :param medida: Medida de la circunferencia del thorax del paciente - :param medidaZ: Altura aproximada donde está colocado el cinturón de electrodos. El cero se marca desde la apófisis del esternón - :param shape: Forma de la reconstrucción "thorax" o "circle" - - :exception ImpetomCError: Devuelve una excepción con el mensaje de error correspondiente - """ - - if(type(pacientName) != str or len(pacientName) <=1 ): - raise ImpetomCError("El nombre debe ser un string y no debe estar vacÃo") - if(type(pacientCi) != str or not re.match('^[0-9]*$',pacientCi)): - raise ImpetomCError("La CI solo puede contener números") - if (type(p)!=float or p <= 0): - raise ImpetomCError("p debe ser un float y mayor que 0") - if (type(medida) != str or not re.match('^[0-9]*$', medida)): - if type(medida) == int and int(medida) < 0 :# explcitamente me fijo si el numero es positivo - raise ImpetomCError("La medida de la circuferencia del tórax solo puede contener números positivos") - elif type(medida )!= int: - raise ImpetomCError("La medida de la circuferencia del tórax solo puede contener números") - if (type(medidaZ) != str or not re.match('^[0-9]*$', medidaZ.strip("-"))): - if type(medidaZ) != int: - raise ImpetomCError("La medida de la altura de colocación del cinturón debe ser un número entero") - - mode=mode.lower() - if type(mode) != str: - raise ImpetomCError("El atributo Mode debe ser un string") - elif mode != "reconstruccion" and mode != "setup": - raise ImpetomCError("Modo de reconstrucción inválido. Debe ser \"Reconstruccion\" o \"Setup\"") - shape=shape.lower() - if shape != "thorax" and shape != "circle": - raise ImpetomCError("Forma para la reconstrucción inválida, debe ser \"Thorax\" o \"Circle\"") - try: - patBirthDate = datetime.strptime(birthDate, "%Y%m%d") - except ValueError: - raise ImpetomCError("La fecha de nacimiento no es válida") - sex=sex.lower() - if (sex != "m" and sex != "f" and sex!="otro"): - raise ImpetomCError ("El sexo del paciente debe ser M, F u Otro") - - @classmethod - def guardarImagenEnHistoriaClinica(cls,pacientName,pacientCi,p,pacBirthDate,pacSex, medida, shape, medidaZ,mode): - """ - Permite el guardado de las imágenes obtenidas en la carpeta correspondiente a la historia clónica del paciente, solamente cuando el dispositivo se encuentra en modo Reconstrucción - - :param pacientName: Nombre del paciente - :param pacientCi: Ci del paciente - :param p: valor de p utilizado durante la reconstrucción - :param birthDate: Fecha de nacimiento del paciente - :param pacSex: Sexo biologico del paciente - :param medida: Medida de la circunferencia del thorax del paciente - :param shape: Forma de la reconstrucción "thorax" o "circle" - :param medidaZ: Altura aproximada donde está colocado el cinturón de electrodos. El cero se marca desde la apófisis del esternón - :param mode: Modo de trabajo del dispositivo. Puede ser "Reconstruccion" o "Setup". Solo guarda imágenes con formato Dicom en caso de estar en modo "Reconstruccion" - """ - - cls.__verificarParametrosParaHistoriaClinica(pacientName,pacientCi,p,pacBirthDate,pacSex,medida,medidaZ,shape,mode) - medida=int(medida) - medidaZ=int(medidaZ) - dir_dcm = "\\Pacients_Data\\" + pacientName.strip('\n') + "_" + pacientCi.strip('\n') + "\\" + cls.today - - try: # intento crear la capeta donde se guardaran las imágenes tomográficas del paciente - os.makedirs(cls.rootDir + dir_dcm) - except OSError: # en caso de que el directorio exista no importa - pass - finally: # guardo la imagen en la carpeta del paciente con un nombre que depende de la hora, minutos y segundos - mode = mode.lower() - if mode == "reconstruccion": - cls.imgDicom.generarImagenDicom(pacientName, pacientCi, pacSex, pacBirthDate, p, cls.lamb, cls.today, medida, shape, medidaZ) diff --git "a/IMPETOM-Cl\303\255nico/ImpetomCElectrodeError.py" "b/IMPETOM-Cl\303\255nico/ImpetomCElectrodeError.py" deleted file mode 100644 index d5cbe13cd8687c1b24cdf590b9d983fc52af3390..0000000000000000000000000000000000000000 --- "a/IMPETOM-Cl\303\255nico/ImpetomCElectrodeError.py" +++ /dev/null @@ -1,16 +0,0 @@ - -class ImpetomCElectrodeError(Exception): - """ - Utilizar esta clase para levantar errores o excepciones con los electrodos - """ - def __init__(self,msg,regularGanancia=False): - """ - Constructor de la clase ImpetomCElectrodeError - - :param msg: Mesaje de error a desplegar con la excepción - :param regularGanancia: Booleano que debe indicar True en caso de que sea un error para regular la ganancia de los electrodos. False se trata de un error de al menos un electrodo desconectado. El valor por defecto de este parámetro es False - - """ - self.regularGanancia=regularGanancia - super().__init__(msg) - diff --git "a/IMPETOM-Cl\303\255nico/ImpetomCError.py" "b/IMPETOM-Cl\303\255nico/ImpetomCError.py" deleted file mode 100644 index 6462d06ca5ed8ed5cb13803ae2b8ee93a98b915b..0000000000000000000000000000000000000000 --- "a/IMPETOM-Cl\303\255nico/ImpetomCError.py" +++ /dev/null @@ -1,15 +0,0 @@ - -class ImpetomCError(Exception): - """ - Utilizar esta clase para levantar errores o excepciones que no son referentes a los electrodos del dispositivo. - Por ejemplo, esta clase es utilizada cuando se detecta una desconexión del dispositivo Impetom durante la adquisición de datos - - """ - - def __init__(self,msg): - """ - Constructor de la clase ImpetomCError - - :param msg: Mesaje de error a desplegar con la excepción - """ - super().__init__(msg) diff --git "a/IMPETOM-Cl\303\255nico/Interfaz.py" "b/IMPETOM-Cl\303\255nico/Interfaz.py" deleted file mode 100644 index 15d7e0249d058019b4d116ba782754727b8c4ab1..0000000000000000000000000000000000000000 --- "a/IMPETOM-Cl\303\255nico/Interfaz.py" +++ /dev/null @@ -1,1162 +0,0 @@ -import threading -import time -import tkinter.ttk -from tkinter import * -from tkinter import messagebox -from PIL import Image, ImageTk -from _datetime import date -import re -from ImpetomC import ImpetomC -from ImpetomCError import ImpetomCError -from ImpetomCElectrodeError import ImpetomCElectrodeError -from datetime import datetime -import winsound - -""" -Clase que genera la interfaz gráfica de la aplicación -""" - -""" -Variables globales de la aplicación -""" - -arduinoImpetom = 0 # 0 indica arduinoImpetom desconectado, 1 indica que esta conectado -Reconstruir = False -mode = "Setup" -img = Image.open('imagenInicial.jpg') -sclRangeEnable = False - -""" -Funciones para validación de datos de entrada -""" - -def validateName(): - """ - Funcion que valida el nombre del paciente ingresado - :return: 0 si existe algun error, 1 si el nombre es correcto (el campo lblNameError no esta vacio) - """ - - ret=0 - patName = txtName.get("1.0", END) - if len(patName) <=1 : - lblNameError.config(text="Este campo no puede estar vacÃo") - else: - ret=1 - lblNameError.config(text="") - return ret - -def validateCI(): - """ - Funcion que valida la CI del paciente ingresado - :return: 0 si existe algun error, 1 si la CI es correcta (el campo lblNameError no esta vacio) - """ - - ret = 0 - patCi = txtCi.get("1.0", END).strip("\n") - lenCI=len(patCi) - if not re.match('^[0-9]*$',patCi): - lblCiError.config(text="La CI solo puede contener números") - elif lenCI <= 6 or lenCI > 8: - lblCiError.config(text="CI inválida") - else: - ret = 1 - lblCiError.config(text="") - return ret - -def arduinoImpetomConected(): - """ - Funcion que verifica que el dispositivoImpetomC esta conectado - :return: 0 si existe algun error, 1 si no - """ - - ret = 1 - global arduinoImpetom - if arduinoImpetom == 0: - try: # Verifico que haya un arduino conectado al equipo al iniciar y si es el arduino de ImpetomC - ImpetomC.startUp() - arduinoImpetom = 1 # indicador que arduino Impetom está conectado - lblError.config(text="", bg='white') - except ImpetomCError as e: - lblError.config(text=str(e), bg='white') - arduinoImpetom = 0 - ret = 0 - return ret - -def validateSexoBiologico(): - """ - Funcion que valida el sexp biologico del paciente ingresado - :return: 0 si existe algun error, 1 si no - """ - - ret = 0 - patSex = cmbBioSex.get().lower() - if patSex == "seleccionar": - lblBioSexError.config(text="Seleccione una opción válida") - else: - lblBioSexError.config(text="") - ret = 1 - return ret - -def validateBirthDate(): - """ - Funcion que valida la fecha de nacimiento del paciente ingresado - :return: 0 si existe algun error, 1 si no - """ - - ret = 0 - txtBDate = str(txtBirthDate.get("1.0", 'end-1c')) - try: - datetime.strptime(txtBDate, "%d-%m-%Y") - lblBirthDateError.config(text="") - ret = 1 - except ValueError: - lblBirthDateError.config(text="La fecha debe ser dd-mm-yyyy") - finally: - return ret - -def validateMedida(): - """ - Función que valida la entrada de los datos de medida de circunferencia del tórax, - El dato debe ser un número entre 100 y 2000mm - """ - - ret = 0 - fantomaMed = txtMedida.get("1.0", END).strip("\n") - lenFantomaMed = len(fantomaMed) - if not re.match('^[0-9]*$', fantomaMed): - lblMedidaError.config(text="Este campo solo puede contener números positivos") - elif lenFantomaMed <= 2: # Verifico que el número sea mayor que 100 mm - lblMedidaError.config(text="El perÃmetro debe ser mayor o igual a 100 mm") - elif lenFantomaMed >= 5: - lblMedidaError.config(text="El perÃmetro es demasiado grande") - else: - ret = 1 - lblMedidaError.config(text="") - if lenFantomaMed == 4: - intFantomaMed = int(fantomaMed) - if intFantomaMed >= 2000: - lblMedidaError.config(text="El perÃmetro es demasiado grande") - ret = 0 - - return ret - -def validateMedidaZ(): - """ - Función que valida la altura de colocación del cinturon, debe estar entre 10 mm y 999mm - """ - - ret = 0 - fantomaMedZ = txtMedidaZ.get("1.0", END).strip("\n") - fantomaMedZ = fantomaMedZ.strip("-") # Para validar ints > 0 y < 0 con la misma regExp - lenFantomaMedZ = len(fantomaMedZ) - lblMedidaZError.place(x=(265 / 1200) * screenWidth, y=(560 / 750) * screenHeight) - if not re.match('^[0-9]*$', fantomaMedZ): - lblMedidaZError.config( - text="La altura de colocación del cinturón debe ser un número entero medido desde la apófisis del esternón") - elif lenFantomaMedZ < 1 or lenFantomaMedZ > 3: # - lblMedidaZError.config(text="La referencia de altura no es válida") - else: - ret = 1 - lblMedidaZError.config(text="") - return ret - -""" -Eventos para botones Start y Stop -""" - -def btnStartClicked(): - """ - Evento del botón start - """ - - global Reconstruir, arduinoImpetom - if validateName() +validateCI() + arduinoImpetomConected() + validateSexoBiologico() + validateBirthDate() + validateMedida() + validateMedidaZ() == 7: - Reconstruir = True - txtMedida.config(state='disable') - txtMedidaZ.config(state='disable') - txtName.config(state='disable') - txtCi.config(state='disable') - btnIncTime.config(state='disable') - btnIncTime2.config(state='disable') - btnDecTime.config(state='disable') - btnDecTime2.config(state='disable') - btnStart.config(state='disable') - lblTimeError.config(text="Presione Stop para cambiar esta opción") - btnReconstruccion.config(state='disable') - btnSetup.config(state='disable') - cmbModel.config(state='disable') - lblModeMessage.config(text='Presione Stop para cambiar esta opción') - btnCalibrar.config(state='disable') - btnReset.config(state='disable') - threading.Thread(target=reloadImage).start() - - -def btnStopClicked(): - """ - Evento del botón Stop - """ - - global Reconstruir - Reconstruir = False - time.sleep(4) - txtMedida.config(state='normal') - txtMedidaZ.config(state='normal') - txtName.config(state='normal') - txtCi.config(state='normal') - btnIncTime.config(state='normal') - btnIncTime2.config(state='normal') - btnDecTime.config(state='normal') - btnDecTime2.config(state='normal') - btnStart.config(state='normal') - btnStop.config(state='disable') - lblTimeError.config(text="") - lblModeMessage.config(text='') - btnCalibrar.config(state='normal') - btnReset.config(state='normal') - if mode == "Setup": - btnReconstruccion.config(state='normal') - else: - btnSetup.config(state='normal') - cmbModel.config(state='readonly') - -def btnResetClicked(): - """ - Evento para el botón reset - """ - - global img, photo - lblDate.config(text="Fecha: " + str(date.today().strftime("%b-%d-%Y"))) - btnReset.config(state='disable') - ImpetomC.reset() - img = Image.open('imagenInicial.jpg') - photo = ImageTk.PhotoImage(img) - lblImg.config(text="", image=photo, width=(700 / 1200) * screenWidth, height=(500 / 750) * screenHeight) - cmbModel.current(0) - lblpRangeValue.config(text=initialPValue) - lblGananciaValue.config(text=initialGValue) - lblVmaxValue.config(text=initialVmaxValue) - lblVminValue.config(text=initialVminValue) - lblSaveTimeValue.config(text=initialSaveTimeValue) - lblError.config(text="", bg="white") - btnSetupClicked() - rbtnSclOptionsDisable.select() - if tkinter.messagebox.askyesno("Reset", "Desea también eliminar los datos del paciente?"): - txtName.delete("1.0", "end") - txtCi.delete("1.0", "end") - txtMedida.delete("1.0", "end") - txtMedidaZ.delete("1.0", "end") - txtBirthDate.delete("1.0", "end") - cmbBioSex.current(0) - -""" -Esta función se encarga de actualizar las imágenes en lblImg -""" - -def reloadImage(): - """ - Esta funcion es la encargada de actualizar las imagenes en la etiqueta lblImg - """ - - global img, photo, arduinoImpetom, Reconstruir, bpWeight, screenWidth, sclRangeEnable, mode - ti = time.time() - while Reconstruir: - try: - medida = txtMedida.get("1.0", END).strip("\n") - medidaZ = txtMedidaZ.get("1.0", END).strip("\n") - vmax = float(lblVmaxValue.cget("text")) - vmin = float(lblVminValue.cget("text")) - pvalue = round(float(lblpRangeValue.cget("text")), 2) - frecValue = str(30000 - int(lblGananciaValue.cget("text")) * 100) - shape = cmbModel.get().lower() - pacBDate = str(datetime.strptime(txtBirthDate.get("1.0", 'end-1c'), "%d-%m-%Y").strftime("%Y%m%d")) - pacSex = cmbBioSex.get() - ImpetomC.generarImagenTomografica(vmax=vmax, screenWidth=screenWidth, sclEnable=sclRangeEnable, vmin=vmin, - mode=mode, shape=shape, p=pvalue, frecuenciaDDS=frecValue) - tf = time.time() - elapsedTime = int(tf - ti) - img = Image.open('IMG.jpg') - photo = ImageTk.PhotoImage(img) - lblImg.config(text="", image=photo) - lblError.config(text="", bg='#2b70e4') - if elapsedTime > int(float(lblSaveTimeValue.cget('text')) * 60): # Conversión de minutos a segundos - ImpetomC.guardarImagenEnHistoriaClinica(pacientName=txtName.get("1.0", END), - pacientCi=txtCi.get("1.0", END), p=pvalue, pacSex=pacSex, - pacBirthDate=pacBDate, medida=medida, shape=shape, - medidaZ=medidaZ, mode=mode) - ti = time.time() - if Reconstruir: - btnStop.config(state='normal') - except ImpetomCError as e: # errores por problemas de conexion del dispositivo Arduino - lblError.config(text=str(e) + " Por favor verifique la conexión y presione start nuevamente", bg='white') - winsound.Beep(440, 500) - Reconstruir = False - arduinoImpetom = 0 # arduino ImpetomC no está conectado - btnStopClicked() - ImpetomC.guardarImagenEnHistoriaClinica(pacientName=txtName.get("1.0", END), - pacientCi=txtCi.get("1.0", END), p=pvalue, pacSex=pacSex, - pacBirthDate=pacBDate, medida=medida, shape=shape, medidaZ=medidaZ, - mode=mode) - except ImpetomCElectrodeError as e: # Errores detectados sobre los electrodos - lblError.config(text=str(e), bg='white', fg='#f00') - tf = time.time() - elapsedTime = int(tf - ti) - img = Image.open('IMG.jpg') - photo = ImageTk.PhotoImage(img) - lblImg.config(text="", image=photo) - if e.regularGanancia and elapsedTime > int(float(lblSaveTimeValue.cget( - 'text')) * 60): # Para errores de regular ganancia se guarda la imágen, si son errores de falso contacto no se guarda la imágen - ImpetomC.guardarImagenEnHistoriaClinica(pacientName=txtName.get("1.0", END), - pacientCi=txtCi.get("1.0", END), p=pvalue, pacSex=pacSex, - pacBirthDate=pacBDate, medida=medida, shape=shape, - medidaZ=medidaZ, mode=mode) - ti = time.time() - elif not e.regularGanancia: - winsound.Beep(440, 500) - if Reconstruir: - btnStop.config(state='normal') - except RuntimeError: # Se esta recontruyendo la imagen y se presiona el botón de salir - time.sleep(5) - root.destroy() - -""" -Funciones botones p del jac -""" -maxPValue = 0.9 -minPValue = 0.05 -def incPRange(): - """ - Evento del boton ">" de p - """ - - enableDecpRange() - pRangeValue = float(lblpRangeValue.cget("text")) - pRangeValue += 0.01 - if pRangeValue >= maxPValue: - pRangeValue = maxPValue - disbleIncpRange() - lblpRangeValue.config(text=str(round(pRangeValue,2))) - -def incPRange2(): - """ - Evento del boton ">>" de p - """ - - enableDecpRange() - pRangeValue = float(lblpRangeValue.cget("text")) - pRangeValue += 0.1 - if pRangeValue >= maxPValue: - pRangeValue = maxPValue - disbleIncpRange() - lblpRangeValue.config(text=str(round(pRangeValue,2))) - -def decPRange(): - """ - Evento del boton "<" de p - """ - - enableIncpRange() - pRangeValue = float(lblpRangeValue.cget("text")) - pRangeValue -= 0.01 - if pRangeValue <= minPValue: - pRangeValue = minPValue - disableDecpRange() - lblpRangeValue.config(text=str(round(pRangeValue,2))) - -def decPRange2(): - """ - Evento del boton "<<" de p - """ - - enableIncpRange() - pRangeValue = float(lblpRangeValue.cget("text")) - pRangeValue -= 0.1 - if pRangeValue <= minPValue: - pRangeValue = minPValue - disableDecpRange() - lblpRangeValue.config(text=str(round(pRangeValue,2))) - -def enableIncpRange(): - """ - Permite habilitar los botones ">>" y ">" de p - """ - - btnIncpRange.config(state="normal") - btnIncpRange2.config(state="normal") - -def enableDecpRange(): - """ - Permite habilitar los botones "<" y "<<" de p - """ - - btnDecpRange.config(state="normal") - btnDecpRange2.config(state="normal") - -def disbleIncpRange(): - """ - Permite deshabilitar los botones ">>" y ">" de p - """ - - btnIncpRange.config(state="disable") - btnIncpRange2.config(state="disable") - -def disableDecpRange(): - """ - Permite deshabilitar los botones "<" y "<<" de p - """ - - btnDecpRange.config(state="disable") - btnDecpRange2.config(state="disable") - -""" -Eventos de los botones para el manejo de la ganancia -""" - -maxGananciaValue = 5 -minGananciaValue = -20 - -def incGanancia(): - """ - Evento del boton ">" de la ganancia del sistema - """ - - enableDecGanancia() - gananciaValue = int(lblGananciaValue.cget("text")) - gananciaValue += 1 - if gananciaValue >= maxGananciaValue: - gananciaValue = maxGananciaValue - disableIncGanancia() - lblGananciaValue.config(text=gananciaValue) - -def incGanancia2(): - """ - Evento del boton ">>" de la ganancia del sistema - """ - - enableDecGanancia() - gananciaValue = int(lblGananciaValue.cget("text")) - gananciaValue += 5 - if gananciaValue >= maxGananciaValue: - gananciaValue = maxGananciaValue - disableIncGanancia() - lblGananciaValue.config(text=gananciaValue) - -def decGanancia(): - """ - Evento del boton "<" de la ganancia del sistema - """ - - enableIncGanancia() - gananciaValue = int(lblGananciaValue.cget("text")) - gananciaValue -= 1 - if gananciaValue <= minGananciaValue: - gananciaValue =minGananciaValue - disableDecGanancia() - lblGananciaValue.config(text=gananciaValue) - -def decGanancia2(): - """ - Evento del boton "<<" de la ganancia del sistema - """ - - enableIncGanancia() - gananciaValue = int(lblGananciaValue.cget("text")) - gananciaValue -= 5 - if gananciaValue <= minGananciaValue: - gananciaValue = minGananciaValue - disableDecGanancia() - lblGananciaValue.config(text=gananciaValue) - -def enableIncGanancia(): - """ - Permite habilitar los botones ">>" y ">" de ganancia - """ - - btnIncGanancia.config(state="normal") - btnIncGanancia2.config(state="normal") - -def enableDecGanancia(): - """ - Permite habilitar los botones "<<" y "<" de ganancia - """ - - btnDecGanancia.config(state="normal") - btnDecGanancia2.config(state="normal") - -def disableIncGanancia(): - """ - Permite deshabilitar los botones ">>" y ">" de ganancia - """ - - btnIncGanancia.config(state="disable") - btnIncGanancia2.config(state="disable") - -def disableDecGanancia(): - """ - Permite deshabilitar los botones "<<" y "<" de ganancia - """ - - btnDecGanancia.config(state="disable") - btnDecGanancia2.config(state="disable") - -""" -Funciones botones para el valor de Vmax -""" - -maxVMAXvalue = 5 -minVMAXvalue = -20 - -def incVmax(): - """ - Evento del boton ">" de vmax - """ - - enableDecVmax() - vmaxValue = float(lblVmaxValue.cget("text")) - vmaxValue += 0.1 - if vmaxValue >= maxVMAXvalue: - vmaxValue = maxVMAXvalue - disableIncVmax() - lblVmaxValue.config(text=str(round(vmaxValue,1))) - -def incVmax2(): - """ - Evento del boton ">>" de vmax - """ - - enableDecVmax() - vmaxValue = float(lblVmaxValue.cget("text")) - vmaxValue += 1 - if vmaxValue >= maxVMAXvalue: - vmaxValue = maxVMAXvalue - disableIncVmax() - lblVmaxValue.config(text=str(round(vmaxValue,1))) - -def decVmax(): - """ - Evento del boton "<" de vmax - """ - enableIncVmax() - vmaxValue = float(lblVmaxValue.cget("text")) - vmaxValue -= 0.1 - if vmaxValue <= minVMAXvalue: - vmaxValue = minVMAXvalue - disableDecVmax() - if vmaxValue > float(lblVminValue.cget("text")): - lblVmaxValue.config(text=str(round(vmaxValue,1))) - -def decVmax2(): - """ - Evento del boton "<<" de vmax - """ - - enableIncVmax() - vmaxValue = float(lblVmaxValue.cget("text")) - vmaxValue -= 1 - if vmaxValue <= minVMAXvalue: - vmaxValue = minVMAXvalue - disableDecVmax() - if vmaxValue > float(lblVminValue.cget("text")): - lblVmaxValue.config(text=str(round(vmaxValue,1))) - -def enableIncVmax(): - """ - Permite habilitar los botones ">>" y ">" de vmax - """ - - btnIncVmax.config(state="normal") - btnIncVmax2.config(state="normal") - -def enableDecVmax(): - """ - Permite habilitar los botones "<<" y "<" de vmax - """ - - btnDecVmax.config(state="normal") - btnDecVmax2.config(state="normal") - -def disableIncVmax(): - """ - Permite deshabilitar los botones ">>" y ">" de vmax - """ - - btnIncVmax.config(state="disable") - btnIncVmax2.config(state="disable") - -def disableDecVmax(): - """ - Permite deshabilitar los botones "<<" y "<" de vmax - """ - - btnDecVmax.config(state="disable") - btnDecVmax2.config(state="disable") - -""" -Funciones botones para el valor de Vmin -""" - -maxVMINValue = 0 -minVMINValue = -40 - -def incVmin(): - """ - Evento del boton ">" de vmin - """ - - enableDecVmin() - VminValue = float(lblVminValue.cget("text")) - VminValue += 0.1 - if VminValue >= maxVMINValue: - VminValue = maxVMINValue - disableIncVmin() - if VminValue < float(lblVmaxValue.cget("text")): - lblVminValue.config(text=str(round(VminValue,1))) - -def incVmin2(): - """ - Evento del boton ">>" de vmin - """ - - enableDecVmin() - VminValue = float(lblVminValue.cget("text")) - VminValue += 1 - if VminValue >= maxVMINValue: - VminValue = maxVMINValue - disableIncVmin() - if VminValue < float(lblVmaxValue.cget("text")): - lblVminValue.config(text=str(round(VminValue,1))) - -def decVmin(): - """ - Evento del boton "<" de vmin - """ - - enableIncVmin() - VminValue = float(lblVminValue.cget("text")) - VminValue -= 0.1 - if VminValue <= minVMINValue: - VminValue = minVMINValue - disableDecVmin() - lblVminValue.config(text=str(round(VminValue,1))) - -def decVmin2(): - """ - Evento del boton "<<" de vmin - """ - - enableIncVmin() - VminValue = float(lblVminValue.cget("text")) - VminValue -= 1 - if VminValue <= minVMINValue: - VminValue = minVMINValue - disableDecVmin() - lblVminValue.config(text=str(round(VminValue,1))) - -def enableIncVmin(): - """ - Permite habilitar los botones ">>" y ">" de vmin - """ - - btnIncVmin.config(state="normal") - btnIncVmin2.config(state="normal") - -def enableDecVmin(): - """ - Permite habilitar los botones "<<" y "<" de vmin - """ - - btnDecVmin.config(state="normal") - btnDecVmin2.config(state="normal") - -def disableIncVmin(): - """ - Permite deshabilitar los botones ">>" y ">" de vmin - """ - - btnIncVmin.config(state="disable") - btnIncVmin2.config(state="disable") - -def disableDecVmin(): - """ - Permite deshabilitar los botones "<<" y "<" de vmin - """ - - btnDecVmin.config(state="disable") - btnDecVmin2.config(state="disable") - - -""" -Funciones para actualizar el modo (Reconstruction o Setup) en pantalla -""" - -def btnReconstruccionClicked(): - """ - Evento del boton modo Reconstruccion - """ - - global mode - mode = "Reconstruccion" - lblModeValue.config(text="Reconstrucción") - btnReconstruccion.config(state='disabled') - btnSetup.config(state='normal') - -def btnSetupClicked(): - """ - Evento del boton modo Setup - """ - global mode - mode = "Setup" - lblModeValue.config(text=mode) - btnReconstruccion.config(state='normal') - btnSetup.config(state='disabled') - -""" -Funciones para obtener el vector de datos homogéneo -""" - -def calibrar(): - """ - Evento del boton calibrar - """ - ImpetomC.actualizarVectorDeDatosHomogeneo() - btnReset.config(state="normal") - -""" -Funciones botones Saved Timed -""" - -maxTimeValue= 120 -minTimeValue = 0.5 -def incTime(): - """ - Evento del boton ">" de tiempo entre imagenes guardadas - """ - - enableDecTime() - timeValue = float(lblSaveTimeValue.cget("text")) - if timeValue == minTimeValue: - timeValue = 1 - else: - timeValue += 1 - if timeValue >= maxTimeValue: - timeValue = maxTimeValue - disbleIncTime() - lblSaveTimeValue.config(text=str(round(timeValue))) - -def incTime2(): - """ - Evento del boton ">>" de tiempo entre imagenes guardadas - """ - - enableDecTime() - timeValue = float(lblSaveTimeValue.cget("text")) - if timeValue == minTimeValue: - timeValue = 5 - else: - timeValue += 5 - if timeValue >= maxTimeValue: - timeValue = maxTimeValue - disbleIncTime() - lblSaveTimeValue.config(text=str(round(timeValue))) - -def decTime(): - """ - Evento del boton "<" de tiempo entre imagenes guardadas - """ - - enableIncTime() - timeValue = float(lblSaveTimeValue.cget("text")) - timeValue -= 1 - if timeValue < minTimeValue: - timeValue = minTimeValue - lblSaveTimeValue.config(text=str(round(timeValue,1))) - disableDecTime() - else: - lblSaveTimeValue.config(text=str(round(timeValue))) - -def decTime2(): - """ - Evento del boton "<<" de tiempo entre imagenes guardadas - """ - - enableIncTime() - timeValue = float(lblSaveTimeValue.cget("text")) - timeValue -= 5 - if timeValue < minTimeValue: - timeValue = minTimeValue - lblSaveTimeValue.config(text=str(round(timeValue,1)))#redondea para colocar 0.5 en pantalla - disableDecTime() - else: - lblSaveTimeValue.config(text=str(round(timeValue))) - -def enableIncTime(): - """ - Permite habilitar los botones ">>" y ">" del tiempo entre imagenes guardadas - """ - - btnIncTime.config(state="normal") - btnIncTime2.config(state="normal") - -def enableDecTime(): - """ - Permite habilitar los botones "<<" y "<" del tiempo entre imagenes guardadas - """ - - btnDecTime.config(state="normal") - btnDecTime2.config(state="normal") - -def disbleIncTime(): - """ - Permite deshabilitar los botones ">>" y ">" del tiempo entre imagenes guardadas - """ - btnIncTime.config(state="disable") - btnIncTime2.config(state="disable") - -def disableDecTime(): - """ - Permite deshabilitar los botones "<<" y "<" del tiempo entre imagenes guardadas - """ - - btnDecTime.config(state="disable") - btnDecTime2.config(state="disable") - - -""" -Funciones de los radioButtons de BP -""" - -def enableScaleOptions(): - """ - Evento del radio button para habilitar las opciones del rango de escala - """ - - global sclRangeEnable - sclRangeEnable = True - enableIncVmin() - enableIncVmax() - enableDecVmin() - enableDecVmax() - - -def disableScaleOptions(): - """ - Evento del radio button para deshabilitar las opciones del rango de escala - """ - - global sclRangeEnable - sclRangeEnable = False - disableDecVmin() - disableDecVmax() - disableIncVmax() - disableIncVmin() - -""" -Función para el control del evento de cierre de la aplicación -""" - -def onClose(): - """ - Evento de cierre de la aplicacion - """ - if tkinter.messagebox.askyesno("Salir","Está seguro que desea salir?"): - global Reconstruir - if Reconstruir: - Reconstruir=False - time.sleep(5)# esto es para que pueda finalizar el programa sin tirar error. Es por si se cierra el programa, con el programa updeteando la imagen - root.destroy() - -""" -Armado de la interfaz -Como nota general, se uso para la escala de la pantalla 1200 (width) y 750 (height), por eso se ven esos números en todo el código de aquà en más. -Esto es porque para la versión incial de la interfaz se utilizó una con ese tamaño y se logró colocar todos los widgets quedando la interfaz agradable a la vista -""" - -if __name__ == '__main__': - - root = Tk() - root.title("Impetom-C app") - screenWidth = root.winfo_screenwidth() - screenHeight = root.winfo_screenheight() - rootSize = str(screenWidth) + "x" + str(screenHeight) - root.geometry(rootSize) - - root.protocol("WM_DELETE_WINDOW", onClose) # manejo del evento de cierre por la cruz de la interfaz - root.resizable(width=False, height=False) # el usuario no puede cambiar el tamaño de la ventana - - """ - Info Impetom + logo fing - """ - - # Se agrega imagen de fondo de la app - bg = PhotoImage(file="fondo_Impetom.png") # color azul fondo #2b70e4 amarillo #eccc6e - # Create Canvas - canvas1 = Canvas(root, width=screenWidth, height=screenHeight) - canvas1.place(x=0, y=0) - canvas1.create_image((0 / 1200) * screenWidth, 0, image=bg, anchor="nw") - - """ - Datos del paciente - #f00 es el color rojo para cualquier SO - """ - lblPatient = Label(root, text="Datos del paciente", bg='#2b70e4', fg='white', font=("Helvetica", 12, "bold")) - lblPatient.place(x=(30 / 1200) * screenWidth, y=(20 / 750) * screenHeight) - - lblDate = Label(root, text="Fecha: " + str(date.today().strftime("%b-%d-%Y")), bg='#2b70e4', fg='white', - font=("Helvetica", 10, "bold")) - lblDate.place(x=(330 / 1200) * screenWidth, y=(20 / 750) * screenHeight) - - lblName = Label(root, text="Nombre:", bg='#2b70e4', fg='white', font=("Helvetica", 10, "bold")) - lblName.place(x=(50 / 1200) * screenWidth, y=(50 / 750) * screenHeight) - txtName = Text(root, width=30, height=1) - txtName.place(x=(105 / 1200) * screenWidth, y=(50 / 750) * screenHeight) - lblNameError = Label(root, fg='red', text="Este campo es obligatorio", bg='#2b70e4', font=("Helvetica", 8, "bold")) - lblNameError.place(x=(100 / 1200) * screenWidth, y=(75 / 750) * screenHeight) - - lblCi = Label(root, text="CI:", bg='#2b70e4', fg='white', font=("Helvetica", 10, "bold")) - lblCi.place(x=(50 / 1200) * screenWidth, y=(100 / 750) * screenHeight) - txtCi = Text(root, width=15, height=1) - txtCi.place(x=(100 / 1200) * screenWidth, y=(100 / 750) * screenHeight) - lblCiError = Label(root, fg='red', text="Este campo es obligatorio", bg='#2b70e4', font=("Helvetica", 8, "bold")) - lblCiError.place(x=(100 / 1200) * screenWidth, y=(125 / 750) * screenHeight) - - lblSexoBiologico = Label(root, text="Sexo:", bg='#2b70e4', fg='white', font=("Helvetica", 10, "bold")) - lblSexoBiologico.place(x=(310 / 1200) * screenWidth, y=(50 / 750) * screenHeight) - cmbBioSex = tkinter.ttk.Combobox(root, values=['Seleccionar', 'M', 'F', 'Otro'], state='readonly', width=10) - cmbBioSex.place(x=(350 / 1200) * screenWidth, y=(50 / 750) * screenHeight) - lblBioSexError = Label(root, text="Este campo es obligatorio", fg='red', bg='#2b70e4', font=("Helvetica", 8, "bold")) - lblBioSexError.place(x=(315 / 1200) * screenWidth, y=(75 / 750) * screenHeight) - cmbBioSex.current(0) - - lblBirthDate = Label(root, text="Fecha de nacimiento:", bg='#2b70e4', fg='white', font=("Helvetica", 10, "bold")) - lblBirthDate.place(x=(215 / 1200) * screenWidth, y=(100 / 750) * screenHeight) - txtBirthDate = Text(root, width=10, height=1) - txtBirthDate.place(x=(350 / 1200) * screenWidth, y=(100 / 750) * screenHeight) - lblBirthDateError = Label(root, text="Formato : dd-mm-yyyy", fg='red', bg='#2b70e4', font=("Helvetica", 8, "bold")) - lblBirthDateError.place(x=(315 / 1200) * screenWidth, y=(125 / 750) * screenHeight) - - """ - Imagen inicial en la app - """ - - photo = ImageTk.PhotoImage(img) - lblImg = Label(root, image=photo, width=(700 / 1200) * screenWidth, height=(500 / 750) * screenHeight) - lblImg.place(x=(445 / 1200) * screenWidth, y=(175 / 750) * screenHeight) - - """ - botones Start, Stop, Calibrar y Reset - """ - - btnStart = Button(root, text="Start", padx=15, pady=2, command=btnStartClicked) - btnStart.place(x=(1030 / 1200) * screenWidth, y=(690 / 750) * screenHeight) - - btnStop = Button(root, text="Stop", padx=10, pady=2, command=btnStopClicked, state='disable') - btnStop.place(x=(1090 / 1200) * screenWidth, y=(690 / 750) * screenHeight) - - btnCalibrar = Button(root, text="Calibrar", command=calibrar) - btnCalibrar.place(x=(400 / 1200) * screenWidth, y=(690 / 750) * screenHeight) - - btnReset = Button(root, text="Reset", command=btnResetClicked, state='disable') - btnReset.place(x=(1100 / 1200) * screenWidth, y=(145 / 750) * screenHeight) - - """ - Control de modo de cambio de modo - """ - - lblMode = Label(root, text="Modo: ", bg='#2b70e4', font=("Helvetica", 12, "bold")) - lblMode.place(x=(140 / 1200) * screenWidth, y=(170 / 750) * screenHeight) - lblModeValue = Label(root, text=mode, bg='#2b70e4', font=("Helvetica", 12)) - lblModeValue.place(x=(190 / 1200) * screenWidth, y=(170 / 750) * screenHeight) - - btnReconstruccion = Button(root, text="Reconstrucción", command=btnReconstruccionClicked, - font=("Helvetica", 10, "bold")) - btnReconstruccion.place(x=(110 / 1200) * screenWidth, y=(195 / 750) * screenHeight) - - btnSetup = Button(root, text="Setup", padx=10, command=btnSetupClicked, state='disable', font=("Helvetica", 10, "bold")) - btnSetup.place(x=(210 / 1200) * screenWidth, y=(195 / 750) * screenHeight) - - lblModeMessage = Label(root, fg='#f00', bg='white') - lblModeMessage.place(x=(80 / 1200) * screenWidth, y=(225 / 750) * screenHeight) - - """ - Opciones para la reconstrucción - Primero el valor p - """ - lblImgOptions = Label(root, text="Opciones de imagen", font=("Helvetica", 10, "bold"), bg='white') - lblImgOptions.place(x=(130 / 1200) * screenWidth, y=(245 / 750) * screenHeight) - - lblp = Label(root, text="p", bg='white') - lblp.place(x=(177 / 1200) * screenWidth, y=(270 / 750) * screenHeight) - initialPValue = "0.2" - lblpRangeValue = Label(root, text=initialPValue, bg='white') # p=0.25 para setup - lblpRangeValue.place(x=(175 / 1200) * screenWidth, y=(295 / 750) * screenHeight) - - btnIncpRange = Button(root, text=">", command=incPRange) - btnIncpRange.place(x=(250 / 1200) * screenWidth, y=(295 / 750) * screenHeight) - - btnIncpRange2 = Button(root, text=">>", command=incPRange2) - btnIncpRange2.place(x=(275 / 1200) * screenWidth, y=(295 / 750) * screenHeight) - - btnDecpRange = Button(root, text="<", command=decPRange) - btnDecpRange.place(x=(100 / 1200) * screenWidth, y=(295 / 750) * screenHeight) - - btnDecpRange2 = Button(root, text="<<", command=decPRange2) - btnDecpRange2.place(x=(67 / 1200) * screenWidth, y=(295 / 750) * screenHeight) - - """ - Control para la frecuencia (ganancia) - """ - lblGanancia = Label(root, text="Ganancia", bg='white') - lblGanancia.place(x=(160 / 1200) * screenWidth, y=(330 / 750) * screenHeight) - initialGValue = "-10" - lblGananciaValue = Label(root, text=initialGValue, bg='white') - lblGananciaValue.place(x=(175 / 1200) * screenWidth, y=(355 / 750) * screenHeight) - - btnIncGanancia = Button(root, text=">", command=incGanancia) - btnIncGanancia.place(x=(250 / 1200) * screenWidth, y=(355 / 750) * screenHeight) - - btnIncGanancia2 = Button(root, text=">>", command=incGanancia2) - btnIncGanancia2.place(x=(275 / 1200) * screenWidth, y=(355 / 750) * screenHeight) - - btnDecGanancia = Button(root, text="<", command=decGanancia) - btnDecGanancia.place(x=(100 / 1200) * screenWidth, y=(355 / 750) * screenHeight) - - btnDecGanancia2 = Button(root, text="<<", command=decGanancia2) - btnDecGanancia2.place(x=(67 / 1200) * screenWidth, y=(355 / 750) * screenHeight) - - """ - Control del rango de escala - """ - - lblSclRangeOptions = Label(root, text="Control de rango de escala", font=("Helvetica", 10, "bold"), bg='white') - lblSclRangeOptions.place(x=(110 / 1200) * screenWidth, y=(400 / 750) * screenHeight) - - rbtnSclOptionsEnable = Radiobutton(root, text="On", variable=0, value=1, command=enableScaleOptions, bg='white') - rbtnSclOptionsEnable.place(x=(280 / 1200) * screenWidth, y=(400 / 750) * screenHeight) - - rbtnSclOptionsDisable = Radiobutton(root, text="Off", variable=0, value=2, command=disableScaleOptions, bg='white') - rbtnSclOptionsDisable.place(x=(320 / 1200) * screenWidth, y=(400 / 750) * screenHeight) - rbtnSclOptionsDisable.select() - """ - Control Vmax - """ - - lblVmax = Label(root, text=" Valor máximo", bg='white') - lblVmax.place(x=(145 / 1200) * screenWidth, y=(425 / 750) * screenHeight) - initialVmaxValue = "0.5" - lblVmaxValue = Label(root, text=initialVmaxValue, bg='white') - lblVmaxValue.place(x=(175 / 1200) * screenWidth, y=(450 / 750) * screenHeight) - - btnIncVmax = Button(root, text=">", command=incVmax) - btnIncVmax.place(x=(250 / 1200) * screenWidth, y=(450 / 750) * screenHeight) - - btnIncVmax2 = Button(root, text=">>", command=incVmax2) - btnIncVmax2.place(x=(275 / 1200) * screenWidth, y=(450 / 750) * screenHeight) - - btnDecVmax = Button(root, text="<", command=decVmax) - btnDecVmax.place(x=(100 / 1200) * screenWidth, y=(450 / 750) * screenHeight) - - btnDecVmax2 = Button(root, text="<<", command=decVmax2) - btnDecVmax2.place(x=(67 / 1200) * screenWidth, y=(450 / 750) * screenHeight) - - """ - Control Vmin - """ - - lblVmin = Label(root, text=" Valor mÃnimo", bg='white') - lblVmin.place(x=(145 / 1200) * screenWidth, y=(480 / 750) * screenHeight) - initialVminValue = "-5.5" - lblVminValue = Label(root, text=initialVminValue, bg='white') - lblVminValue.place(x=(175 / 1200) * screenWidth, y=(510 / 750) * screenHeight) - - btnIncVmin = Button(root, text=">", command=incVmin) - btnIncVmin.place(x=(250 / 1200) * screenWidth, y=(510 / 750) * screenHeight) - - btnIncVmin2 = Button(root, text=">>", command=incVmin2) - btnIncVmin2.place(x=(275 / 1200) * screenWidth, y=(510 / 750) * screenHeight) - - btnDecVmin = Button(root, text="<", command=decVmin) - btnDecVmin.place(x=(100 / 1200) * screenWidth, y=(510 / 750) * screenHeight) - - btnDecVmin2 = Button(root, text="<<", command=decVmin2) - btnDecVmin2.place(x=(67 / 1200) * screenWidth, y=(510 / 750) * screenHeight) - - """ - Control del Modelo - """ - - lblContorno = Label(root, text="Especificaciones de contorno", font=("Helvetica", 10, "bold"), bg='white') - lblContorno.place(x=(110 / 1200) * screenWidth, y=(550 / 750) * screenHeight) - - lblModel = Label(root, text="Forma", bg='white') - lblModel.place(x=(160 / 1200) * screenWidth, y=(575 / 750) * screenHeight) - - cmbModel = tkinter.ttk.Combobox(root, values=['Thorax', 'Circle'], state='readonly') - cmbModel.place(x=(120 / 1200) * screenWidth, y=(600 / 750) * screenHeight) - cmbModel.current(0) # el valor inicial de comboBox es Thorax - - """ - Control de Medida - """ - - lblMedida = Label(root, text="PerÃmetro (mm)", bg='white') - lblMedida.place(x=(260 / 1200) * screenWidth, y=(575 / 750) * screenHeight) - - txtMedida = Text(root, width=4, height=1) - txtMedida.place(x=(280 / 1200) * screenWidth, y=(600 / 750) * screenHeight) - - lblMedidaError = Label(root, text="Campo obligatorio", fg='#f00', bg='white') - lblMedidaError.place(x=(265 / 1200) * screenWidth, y=(620 / 750) * screenHeight) - - """ - Control de Medida_Z - """ - - lblMedidaZ = Label(root, text="Altura (mm)", bg='white') - lblMedidaZ.place(x=(350 / 1200) * screenWidth, y=(575 / 750) * screenHeight) - - txtMedidaZ = Text(root, width=4, height=1) - txtMedidaZ.place(x=(360 / 1200) * screenWidth, y=(600 / 750) * screenHeight) - - lblMedidaZError = Label(root, text="Campo obligatorio", fg='#f00', bg='white') - lblMedidaZError.place(x=(345 / 1200) * screenWidth, y=(550 / 750) * screenHeight) - - """ - Control de tiempos para guardado de imágenes para historia clÃnica - """ - - lblSaveTime = Label(root, text="Tiempo de guardado (min)", font=("Helvetica", 10, "bold"), bg='white') - lblSaveTime.place(x=(100 / 1200) * screenWidth, y=(635 / 750) * screenHeight) - initialSaveTimeValue = "5" - lblSaveTimeValue = Label(root, text=initialSaveTimeValue, bg='white') - lblSaveTimeValue.place(x=(175 / 1200) * screenWidth, y=(665 / 750) * screenHeight) - - btnIncTime = Button(root, text=">", command=incTime) - btnIncTime.place(x=(250 / 1200) * screenWidth, y=(665 / 750) * screenHeight) - - btnIncTime2 = Button(root, text=">>", command=incTime2) - btnIncTime2.place(x=(275 / 1200) * screenWidth, y=(665 / 750) * screenHeight) - - btnDecTime = Button(root, text="<", command=decTime) - btnDecTime.place(x=(100 / 1200) * screenWidth, y=(665 / 750) * screenHeight) - - btnDecTime2 = Button(root, text="<<", command=decTime2) - btnDecTime2.place(x=(67 / 1200) * screenWidth, y=(665 / 750) * screenHeight) - - lblTimeError = Label(root, text="", fg='#f00', bg='white') - lblTimeError.place(x=(100 / 1200) * screenWidth, y=(700 / 750) * screenHeight) - - """ - Por problemas con Arduino al inicio de la aplicación - #2b70e4es el color azul de la imagen del banner - """ - - lblError = Label(root, text="", bg='#2b70e4', font=("Helvetica", 10, "bold"), fg="red") - lblError.place(x=(440 / 1200) * screenWidth, y=(150 / 750) * screenHeight) - disableScaleOptions() # Comienzo el programa con la escala deshabilitada - try: - ImpetomC.startUp() - arduinoImpetom = 1 # Indicador que arduinoImpetom esta conectado - except ImpetomCError as e: - lblError.config(text=str(e) + " Revise la conexión al dispositivo y presione Start", bg='white') - arduinoImpetom = 0 - - root.mainloop() diff --git "a/IMPETOM-Cl\303\255nico/fondo_Impetom.png" "b/IMPETOM-Cl\303\255nico/fondo_Impetom.png" deleted file mode 100644 index 56f7765d708e79a2da51fa72aab4a69e26ff3646..0000000000000000000000000000000000000000 Binary files "a/IMPETOM-Cl\303\255nico/fondo_Impetom.png" and /dev/null differ diff --git "a/IMPETOM-Cl\303\255nico/homo_py.txt" "b/IMPETOM-Cl\303\255nico/homo_py.txt" deleted file mode 100644 index 75716c6982405a69839ac455b51daf31ed35faad..0000000000000000000000000000000000000000 --- "a/IMPETOM-Cl\303\255nico/homo_py.txt" +++ /dev/null @@ -1,208 +0,0 @@ -3.7732160312805476 -2.1896383186705766 -1.2805474095796676 -1.3880742913000979 -0.9188660801564027 -0.7526881720430108 -0.9530791788856305 -0.8015640273704789 -1.2072336265884653 -0.8113391984359726 -1.0117302052785924 -1.3734115347018572 -2.7614858260019552 -3.260019550342131 -3.0254154447702835 -1.76930596285435 -1.050830889540567 -0.967741935483871 -1.6177908113391983 -0.9628543499511242 -1.3782991202346042 -0.9042033235581622 -0.884652981427175 -1.0019550342130987 -1.0410557184750733 -3.260019550342131 -3.7732160312805476 -2.5219941348973607 -1.4711632453567938 -0.8699902248289345 -0.9970674486803519 -1.2903225806451613 -1.3734115347018572 -0.8113391984359726 -0.9237536656891495 -1.2121212121212122 -0.8602150537634409 -1.2854349951124144 -2.5464320625610948 -2.9912023460410557 -2.409579667644184 -1.4027370478983383 -1.8132942326490713 -1.0654936461388074 -1.490713587487781 -0.9139784946236559 -1.0899315738025415 -1.2463343108504399 -1.1925708699902249 -1.3440860215053763 -1.632453567937439 -2.952101661779081 -3.3040078201368526 -2.2434017595307916 -1.3098729227761485 -0.7771260997067448 -1.3636363636363635 -0.8064516129032258 -1.0312805474095796 -0.6842619745845552 -0.7820136852394917 -1.2512218963831867 -1.6764418377321604 -1.1974584555229717 -3.3528836754643208 -3.4408602150537635 -3.479960899315738 -2.018572825024438 -1.1779081133919844 -0.8651026392961877 -0.7673509286412512 -0.9824046920821115 -0.9530791788856305 -0.7820136852394917 -1.8084066471163245 -1.0703812316715542 -1.7497556207233627 -2.6930596285434993 -2.952101661779081 -2.2434017595307916 -1.3098729227761485 -0.9433040078201369 -0.8455522971652004 -1.0019550342130987 -1.383186705767351 -0.8602150537634409 -0.9481915933528837 -1.4418377321603129 -1.4711632453567938 -1.383186705767351 -3.4457478005865103 -3.313782991202346 -2.697947214076246 -1.5689149560117301 -0.9237536656891495 -0.6891495601173021 -0.7380254154447703 -0.6500488758553274 -1.3685239491691104 -0.8211143695014663 -1.2854349951124144 -0.8651026392961877 -1.3978494623655915 -2.849462365591398 -3.509286412512219 -2.4682306940371457 -1.4320625610948192 -0.9286412512218963 -1.3929618768328447 -0.8260019550342131 -1.4222873900293256 -0.8699902248289345 -1.490713587487781 -0.9188660801564027 -0.9824046920821115 -1.4222873900293256 -3.0205278592375366 -3.225806451612903 -3.318670576735093 -1.9403714565004888 -1.1388074291300099 -1.35386119257087 -1.632453567937439 -0.9726295210166178 -1.1094819159335287 -0.9872922776148583 -0.9188660801564027 -1.2805474095796676 -1.1388074291300099 -3.0791788856304985 -3.005865102639296 -2.2140762463343107 -1.295210166177908 -1.3147605083088953 -0.7917888563049853 -1.2218963831867058 -0.7478005865102639 -0.8699902248289345 -0.9042033235581622 -1.217008797653959 -1.1827956989247312 -1.4173998044965788 -3.2160312805474094 -3.5777126099706744 -3.455522971652004 -2.018572825024438 -1.1827956989247312 -0.7966764418377321 -1.4565004887585533 -0.8895405669599218 -0.6647116324535679 -1.2512218963831867 -0.855327468230694 -0.967741935483871 -1.412512218963832 -3.294232649071359 -3.450635386119257 -2.297165200391007 -1.3440860215053763 -0.83088954056696 -1.520039100684262 -1.5493646138807429 -0.9237536656891495 -1.050830889540567 -1.2463343108504399 -0.7917888563049853 -1.2805474095796676 -1.3196480938416422 -3.0303030303030303 -3.4946236559139785 -3.1573802541544476 -1.8377321603128054 -1.0801564027370478 -1.2365591397849462 -0.7331378299120235 -1.0068426197458455 -0.6744868035190615 -1.2903225806451613 -1.4613880742913001 -0.8797653958944281 -1.300097751710655 -3.2844574780058653 -2.844574780058651 -2.7614858260019552 -1.6080156402737047 -0.9775171065493646 -0.8993157380254154 -0.9384164222873901 -1.2121212121212122 -1.0899315738025415 -1.2463343108504399 -0.7917888563049853 -0.8504398826979472 -1.3440860215053763 -3.064516129032258 -3.0009775171065494 -3.4164222873900294 -1.9745845552297165 -1.1583577712609971 -0.7575757575757576 -0.7526881720430108 -0.7526881720430108 -1.2218963831867058 -0.7380254154447703 -0.8015640273704789 -1.270772238514174 -1.2805474095796676 -3.2355816226783967 diff --git "a/IMPETOM-Cl\303\255nico/imagenInicial.jpg" "b/IMPETOM-Cl\303\255nico/imagenInicial.jpg" deleted file mode 100644 index 9f6367a3fd25999ac745ec5975fc55378dfebda0..0000000000000000000000000000000000000000 Binary files "a/IMPETOM-Cl\303\255nico/imagenInicial.jpg" and /dev/null differ