From 6c6f25377d39bb0bf26ed5f146701306e2f7fc7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9uren=20F=2E=20Bechlin?= Date: Fri, 17 Jun 2016 16:03:47 -0300 Subject: [PATCH] =?UTF-8?q?ATT:=20empacotamento=20e=20desenpacotamento=20d?= =?UTF-8?q?e=20dados=20do=20respir=C3=B4metro,=20read-me=20com=20instru?= =?UTF-8?q?=C3=A7=C3=B5es=20de=20uso?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + Makefile | 13 +++- scripts/coleta_script.py | 125 ++++++++++++++++++++------------------ scripts/terminalcolors.py | 4 +- sources/armazenamento.py | 87 ++++++++++++++------------ sources/terminalcolors.py | 58 ++++++++++++++++++ sources/visualiza.py | 22 +++---- 7 files changed, 196 insertions(+), 114 deletions(-) create mode 100644 sources/terminalcolors.py diff --git a/.gitignore b/.gitignore index aeb3942..6bb1365 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ sources/python/ sources/*.log sources/*.logbin +logs/* __pycache__ scripts/__pycache__ diff --git a/Makefile b/Makefile index 30d8cb7..d535ac7 100644 --- a/Makefile +++ b/Makefile @@ -12,8 +12,10 @@ help: @ echo " firmware Compile and upload the firmware to the Arduino board via serial" @ echo " serial Starts a serial session with Python for board communication" @ echo "" - @ echo " store Execute the logger on the foreground. Hit Ctrl+C to stop it." - @ echo " analyse Execute the analyses data routine" + @ echo " run Execute the storage and analysis scripts. It's like run 'make store'" + @ echo " and 'make anlyse'." + @ echo " store Execute the storage data routine." + @ echo " analyze Execute the analysis data routine." install-debian-deps: sudo apt-get install -y python3 supervisor curl dialog @@ -42,5 +44,10 @@ pyserial: python3 -i scripts/init_serial.py run: - python3 logger/run.py + python3 scripts/coleta_script.py +store: + python3 scripts/coleta_script.py --store + +analyze: + python3 scripts/coleta_script.py --analyze diff --git a/scripts/coleta_script.py b/scripts/coleta_script.py index d05d8be..7386f48 100644 --- a/scripts/coleta_script.py +++ b/scripts/coleta_script.py @@ -1,5 +1,7 @@ -from terminalcolors import cprint, cstring -import argparse, subprocess, readchar, sys, os +import os, sys + +from terminalcolors import colorprint, colorstring +import argparse, subprocess, readchar # CONSTANTES LOGPATH = 'logs/' @@ -14,8 +16,8 @@ def get_plataformio_serial_ports(): ''' serial_raw = shexec("platformio serialports list").splitlines() if serial_raw == []: - return ['/dev/tty/USB0'] - # return [] + # return ['/dev/tty/USB0'] + return [] else: serial_ports = [serial_raw[i-1] for i,x in enumerate(serial_raw) if '----' in x] @@ -24,7 +26,7 @@ def get_plataformio_serial_ports(): def serial_ports_menu(): serials_available = get_plataformio_serial_ports() if(serials_available == []): - print("{} nenhuma porta serial encontrada.\nAbortando.".format(cstring("ERRO:", attr='bold'))) + print("{} nenhuma porta serial encontrada.\nAbortando.".format(colorstring("ERRO:", attr='bold'))) sys.exit(0) else: index = 0 @@ -32,7 +34,7 @@ def serial_ports_menu(): while(charac != '\r'): print('\r', end = "", flush=True) for i, ser in enumerate(serials_available): - print("{} {} ".format(cstring("-->", fore='green') if index == i else " " ,ser), end = "", flush=True) + print("{} {} ".format(colorstring("-->", fore='green') if index == i else " " ,ser), end = "", flush=True) charac = readchar.readkey() if(charac == '\x1b[C'): if(index != len(serials_available) - 1): @@ -47,12 +49,12 @@ def serial_ports_menu(): return serials_available[index] def storage_info(inputDic): - cprint("Armazenamento:", attr='bold') + colorprint("Armazenamento:", attr='bold') print("-Nome do arquivo: {} \t-Tempo de armazenamento: {} s".format(inputDic['fileName'],inputDic['execTime'])) - print("-Porta Serial: {} \t -Baud Rate: {} ".format(inputDic['serialPort'],inputDic['baudRate'])) + print("-Porta Serial: {} \t-Baud Rate: {} ".format(inputDic['serialPort'],inputDic['baudRate'])) def visualization_info(inputDic): - cprint("Visualização:", attr='bold') + colorprint("Visualização:", attr='bold') print("Tempo:\t\t\tFrequência:\t\t\tFiltro:") print("-Inicial: {} s\t\t-Inicial: {} Hz\t\t\t-Ordem: {}".format(inputDic['initialTime'],inputDic['initialFreq'], inputDic['filterOrder'])) print("-Final: {} s\t\t-Final: {} Hz\t\t\t-Passadas: {}".format(inputDic['finalTime'],inputDic['finalFreq'], inputDic['filterNum'])) @@ -64,9 +66,6 @@ def visualization_menu_change_time(inputDic): break except ValueError: print("Insira um número válido") - except KeyboardInterrupt: - print("Tecla de escape prescionada.\nAbortando") - sys.exit(1) while True: try: @@ -74,9 +73,6 @@ def visualization_menu_change_time(inputDic): break except ValueError: print("Insira um número válido") - except KeyboardInterrupt: - print("Tecla de escape prescionada.\nAbortando") - sys.exit(1) return inputDic def visualization_menu_change_freq(inputDic): @@ -86,9 +82,6 @@ def visualization_menu_change_freq(inputDic): break except ValueError: print("Insira um número válido") - except KeyboardInterrupt: - print("Tecla de escape prescionada.\nAbortando") - sys.exit(1) while True: try: @@ -96,9 +89,6 @@ def visualization_menu_change_freq(inputDic): break except ValueError: print("Insira um número válido") - except KeyboardInterrupt: - print("Tecla de escape prescionada.\nAbortando") - sys.exit(1) return inputDic def visualization_menu_change_filter(inputDic): @@ -108,9 +98,6 @@ def visualization_menu_change_filter(inputDic): break except ValueError: print("Insira um número válido") - except KeyboardInterrupt: - print("Tecla de escape prescionada.\nAbortando") - sys.exit(1) while True: try: @@ -118,9 +105,6 @@ def visualization_menu_change_filter(inputDic): break except ValueError: print("Insira um número válido") - except KeyboardInterrupt: - print("Tecla de escape prescionada.\nAbortando") - sys.exit(1) return inputDic def visualization_menu(inputDic): @@ -133,7 +117,7 @@ def visualization_menu(inputDic): while(charac != '\r'): print('\r', end = "", flush=True) for i, ser in enumerate(options): - print("{} {} ".format(cstring("-->", fore='green') if index == i else " " ,ser), end = "", flush=True) + print("{} {} ".format(colorstring("-->", fore='green') if index == i else " " ,ser), end = "", flush=True) charac = readchar.readkey() if(charac == '\x1b[C'): if(index != len(options) - 1): @@ -153,10 +137,10 @@ def visualization_menu(inputDic): inputDic = visualization_menu_change_filter(inputDic) return inputDic -def runScripts(inputDic, store=True, visu=True): +def runScripts(inputDic, store=True, analyze=True): if not os.access(inputDic['logPath'], os.R_OK): os.mkdir(inputDic['logPath']) - if store and visu: + if store and analyze: os.system(""" python3 {srcPath}armazenamento.py {serialPort} {baudRate} \ {logPath}{fileName} {execTime} && @@ -168,7 +152,7 @@ def runScripts(inputDic, store=True, visu=True): python3 {srcPath}armazenamento.py {serialPort} {baudRate} \ {logPath}{fileName} {execTime} """.format(**inputDic)) - elif visu: + elif analyze: os.system(""" python3 {srcPath}visualiza.py {logPath}{fileName} {initialTime} \ {finalTime} {filterOrder} {filterNum} {initialFreq} {finalFreq} @@ -178,38 +162,63 @@ def checkPath(path): a = os.getcwd().split('respirometro')[1] return "../"*a.count('/')+path -def main(): - cprint("--: Script de coleta e visualização Respirômetro CTA :--", attr='bold', fore='green') +def main(store=True, analyze=True): + colorprint("--: Script de coleta e visualização Respirômetro CTA :--", attr='bold', fore='green') inputDic = {'initialTime': 0, 'initialFreq': 0, 'finalFreq': 1, 'baudRate': 115200, 'filterOrder':2, 'filterNum':4, 'srcPath':checkPath(SOURCEPATH), 'logPath':checkPath(LOGPATH)} - cprint("\nArmazenamento:", fore='green') - inputDic['fileName'] = input("Insira o nome do arquivo em qual será salvo a coleta: ") + '.log' - print("Selecione a porta usb em que o microcontrolador está conectado.") - print("Use as teclas direcionais para navegar e enter para selecionar") - inputDic['serialPort'] = serial_ports_menu() - while True: - try: - inputDic['execTime'] = int(input("Insira o tempo de armazenamento de dados: ")) - break - except ValueError: - print("Insira um número válido") - except KeyboardInterrupt: - print("Tecla de escape prescionada.\nAbortando") - sys.exit(1) - inputDic['finalTime'] = inputDic['execTime'] - cprint("\nVisualização:", fore='green') - cprint("Default:", attr='bold') - visualization_info(inputDic) - inputDic = visualization_menu(inputDic) - cprint("\nConfirmação:", fore='green') - storage_info(inputDic) - visualization_info(inputDic) - runScripts(inputDic) + if store: + colorprint("\nArmazenamento:", fore='green') + inputDic['fileName'] = input("Insira o nome do arquivo em qual será salvo a coleta: ") + '.log' + print("Selecione a porta usb em que o microcontrolador está conectado.") + print("Use as teclas direcionais para navegar e enter para selecionar") + inputDic['serialPort'] = serial_ports_menu() + while True: + try: + inputDic['execTime'] = int(input("Insira o tempo de armazenamento de dados, em segundos: ")) + break + except ValueError: + print("Insira um número válido") + else: + colorprint("\nVisualização:", fore='green') + inputDic['fileName'] = input("Insira o nome do arquivo que será analisado: ") + '.log' + while True: + try: + inputDic['execTime'] = int(input("Insira o tempo final de análise, em segundos: ")) + break + except ValueError: + print("Insira um número válido") + if analyze: + inputDic['finalTime'] = inputDic['execTime'] + colorprint("\nVisualização:", fore='green') + colorprint("Default:", attr='bold') + visualization_info(inputDic) + inputDic = visualization_menu(inputDic) + colorprint("\nConfirmação:", fore='green') + if store and analyze: + storage_info(inputDic) + visualization_info(inputDic) + runScripts(inputDic) + elif store: + storage_info(inputDic) + runScripts(inputDic, store=True, analyze=False) + else: + visualization_info(inputDic) + runScripts(inputDic, store=False, analyze=True) if __name__ == "__main__": #Creating a parser parser = argparse.ArgumentParser(description="""Script para realizar armazenamento e visualização dos dados do respirômetro.""") - parser.add_argument('--foo', help='foo of the %(prog)s program') - main() + parser.add_argument('--store', action='store_true', + help='Para realizar armazenamento dos dados enviados pela porta serial.') + parser.add_argument('--analyze', action='store_true', + help='Para realizar armazenamento dos dados enviados pela porta serial.') + args = parser.parse_args() + try: + if not args.store and not args.analyze: + main() + else: + main(store=args.store, analyze=args.analyze) + except KeyboardInterrupt: + print("\nTecla de escape prescionada.\nAbortando") diff --git a/scripts/terminalcolors.py b/scripts/terminalcolors.py index df33740..95943ac 100644 --- a/scripts/terminalcolors.py +++ b/scripts/terminalcolors.py @@ -48,9 +48,9 @@ class TerminalColors: print(cls.cstring(string, attr, fore, back), end = end, sep = sep, flush = flush) -def cprint(*args, **kwargs): +def colorprint(*args, **kwargs): TerminalColors.cprint(*args, **kwargs) -def cstring(*args, **kwargs): +def colorstring(*args, **kwargs): return TerminalColors.cstring(*args, **kwargs) if __name__ == '__main__': diff --git a/sources/armazenamento.py b/sources/armazenamento.py index da9c71e..4c9e23b 100644 --- a/sources/armazenamento.py +++ b/sources/armazenamento.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- + +import os, sys +sys.path.append('{}respirometro{}scripts'.format( + os.path.dirname(os.path.realpath(__file__)).split('respirometro')[0], + os.path.sep)) + ''' Respirômetro - Fisiolog CTA @@ -28,8 +34,8 @@ STRUCT_DATA = 'hhh' STRUCT_HEADER = 'Hh' # Exemplo: python3 armazenamento.py /dev/ttyACM0 115200 coleta_Nome_Exemplo_1min.log 30 -from terminalcolors import cprint, cstring -import sys, serial, datetime, os, time, struct +from terminalcolors import colorprint, colorstring +import serial, datetime, time, struct def validateInput(): ''' @@ -74,11 +80,10 @@ def progressBar(percent, lenght=15, description =""): ''' highlight = " "*int((lenght-2)*percent*1.0/100) notHighlight = " "*(lenght - len(highlight) - 2) - printString = "\t"+ cstring(" ", back = "White")+cstring("{}", back = "Green").format(highlight)+ \ + printString = "\t"+ colorstring(" ", back = "White")+colorstring("{}", back = "Green").format(highlight)+ \ "\033[0;0m"+"{}".format(notHighlight)+ "\033[47m"+" "\ "\033[0;32m"+"\t{}%".format(percent)+"\033[0;0m" print(printString, end='\r') - printS def main(): args = validateInput() @@ -148,45 +153,47 @@ def main(): comm.close() print("\nOperação finalizada com sucesso.") -def unpackDataResp(fileName, timeI, timeF): - fisiologfile = open(fileName) - yCard = [] - yRespDir = [] - yRespEsq = [] - x = [] +def unpackData(file_name): + log_file = open(file_name) # Lendo HEADER - fisiologfile.readline() - frequency = fisiologfile.readline().replace('\n', '').split(' ')[4] - linha = fisiologfile.readline() + log_file.readline() + frequency = log_file.readline().replace('\n', '').split(' ')[4] + linha = log_file.readline() date_time_d = linha.split(' ')[6] date_time_d = date_time_d.split('-')[2]+ '/' + date_time_d.split('-')[1]+ '/' + date_time_d.split('-')[0] date_time_h = linha.replace('\n','').split(' ')[7] - fisiologfile.readline() - fisiologfile.readline() - # Dados - if(timeF == 0): - for i, linha in enumerate(fisiologfile): - time = float(linha.replace('\n', '').split('\t')[3]) - if time >= timeI: - yCard.append(int(linha.split('\t')[0])) - yRespDir.append(int(linha.split('\t')[1])) - yRespEsq.append(int(linha.split('\t')[2])) - x.append(time) - else: - for i, linha in enumerate(fisiologfile): - time = float(linha.replace('\n', '').split('\t')[3]) - if time >= timeI and time <= timeF: - yCard.append(int(linha.split('\t')[0])) - yRespDir.append(int(linha.split('\t')[1])) - yRespEsq.append(int(linha.split('\t')[2])) - x.append(time) - fisiologfile.close() - if(len(yCard) % 2 != 0): - del(yCard[-1]) - del(yRespDir[-1]) - del(yRespEsq[-1]) - del(x[-1]) - return {'Freq':frequency, 'Date':date_time_d, 'Hour':date_time_h, 'Cardiogram':yCard, 'RespDir':yRespDir, 'RespEsq':yRespEsq, 'Time': x} + log_file.readline() + fields = log_file.readline().strip(' #(s)\n').split('\t') + + data = {x:[] for x in fields} + for linha in log_file: + items = linha.replace('\n', '').split('\t') + for i, field in enumerate(fields): + data[field].append(float(items[i])) + log_file.close() + + if(len(data[fields[0]]) % 2 != 0): + for item in data.values(): + item.pop(-1) + + header = {'Freq':frequency, 'Date':date_time_d, 'Hour':date_time_h} + data.update(header) + return data + +def selectDataRange(data, key, t_in, t_fi): + if not key in data.keys(): + return False + + list_keys = [x for x in data.keys() if isinstance(data[x], list)] + out = {x:[] for x in data.keys() if x in list_keys} + out.update({x:y for (x,y) in zip(data.keys(), data.values()) if not x in list_keys}) + for i, time in enumerate(data[key]): + if time >= t_in and time < t_fi: + for field in list_keys: + out[field].append(data[field][i]) + return out if __name__== '__main__': - main() + # main() + a = unpackData('../logs/test.log') + b = selectDataRange(a, 'Tempo', 9.0, 9.5) diff --git a/sources/terminalcolors.py b/sources/terminalcolors.py new file mode 100644 index 0000000..95943ac --- /dev/null +++ b/sources/terminalcolors.py @@ -0,0 +1,58 @@ +class TerminalColors: + ''' + Reference http://ascii-table.com/ansi-escape-sequences.php + ''' + class ATTRIBUTES: + NORMAL = '' + BOLD = ';1' + UNDERSCORE = ';4' + BLINK = ';5' + REVERSE = ';6' + CONCEALED = ';7' + + class FOREGROUND: + NORMAL = '' + BLACK = ';30' + RED = ';31' + GREEN = ';32' + YELLOW = ';33' + BLUE = ';34' + MAGENTA = ';35' + CYAN = ';36' + WHITE = ';37' + + class BACKGROUND: + NORMAL = '' + BLACK = ';40' + RED = ';41' + GREEN = ';42' + YELLOW = ';43' + BLUE = ';44' + MAGENTA = ';45' + CYAN = ';46' + WHITE = ';47' + + @classmethod + def cstring(cls, string, attr = 'NORMAL', fore = 'NORMAL', back = 'NORMAL'): + attr = getattr(cls.ATTRIBUTES, attr.upper(), '') + fore = getattr(cls.FOREGROUND, fore.upper(), '') + back = getattr(cls.BACKGROUND, back.upper(), '') + format_str = attr + fore + back + if(format_str != ''): + format_str = format_str[1:] + return '\033[{}m{}\033[0m'.format(format_str, string) + + @classmethod + def cprint(cls, string, attr = 'NORMAL', fore = 'NORMAL', back = 'NORMAL', + sep = ' ', end = '\n', flush = False): + + print(cls.cstring(string, attr, fore, back), end = end, sep = sep, flush = flush) + +def colorprint(*args, **kwargs): + TerminalColors.cprint(*args, **kwargs) +def colorstring(*args, **kwargs): + return TerminalColors.cstring(*args, **kwargs) + +if __name__ == '__main__': + cprint('TEST', fore='green', back = 'blue') + print(cstring('TESTE', fore='blue', back='green')) diff --git a/sources/visualiza.py b/sources/visualiza.py index 29614c3..2b91882 100644 --- a/sources/visualiza.py +++ b/sources/visualiza.py @@ -38,7 +38,7 @@ from array import * from scipy.fftpack import fft, fftfreq, fftshift import numpy as np -from armazenamento import unpackDataResp +from armazenamento import unpackData, selectDataRange import sys, os, re, math import matplotlib.pyplot as plt @@ -55,15 +55,14 @@ if not os.path.exists(sys.argv[1]): # Atribuindo as váriaveis com os valores de entrada parametro = sys.argv[1:] log_file = parametro[0] -fisiologfile = open(log_file,'r') t_inicial = int(parametro[1]) t_final = int(parametro[2]) n_filtro = int(parametro[3]) qtd_filtro = int(parametro[4]) freq_i = float(parametro[5]) freq_f = float(parametro[6]) -png_name = 'Resp_'+str(log_file.split('/')[:-1])+'_'+str(t_inicial)+'_a_'+str(t_final)+'_'+str('%.2f' % freq_i)+'_a_'+str('%.2f' % freq_f)+'.png' -user_name = log_file +user_name = os.path.splitext(os.path.basename(log_file))[0] +png_name = 'Resp_{}_{}s_{}s_{}hz_{}hz.png'.format(user_name, t_inicial, t_final, freq_i, freq_f) # ERRO: # Ajustando para que os pontos iniciais não sejam maiores que os finais @@ -81,17 +80,18 @@ if t_inicial < 0 or t_final < 0: sys.stderr.write('ERRO: Não possível operar com intervalos negativos.\nEm caso de dúvidas leia o READ_ME.md.\n') sys.exit(1) -data = unpackDataResp(log_file, t_inicial , t_final) - +data = unpackData(log_file) freq = float(data['Freq']) -N = len(data['Cardiogram']) +N = len(data['A0']) T = 1.0/freq dx = float(freq)/N +data = selectDataRange(data, 'Tempo', t_inicial, t_final) + # Inicialização de variáveis -x1 = array('f', data['Time']) -y1 = array('f', data['RespDir']) -y2 = array('f', data['RespEsq']) +x1 = array('f', data['Tempo']) +y1 = array('f', data['A0']) +y2 = array('f', data['A1']) y1_filt = array('f', []) y2_filt = array('f', []) x_fft_plot = array('f', []) @@ -382,7 +382,7 @@ while True: aux_str = aux_str[reg_exp.end():] else: break -local_dir += png_name +local_dir += '/' + png_name fig.savefig(local_dir, dpi=400) #plt.show() -- 2.22.0