def socket_client(DataS, ShutDown, Connection, LockQ): cpr.SetPriority(1) PreMessage = MESSAGE_PRELOAD() while not ShutDown.is_set(): try: CwtFreq = DataS.get(GETBLOCK, GETTIMEOUT) Message = sp.MessageReturn(CwtFreq.value * DB) ar_type = DOUBLE * CwtFreq.value break except queue.Empty: continue except EOFError: ShutDown.set() break i = 0 ch = 0 try: while not ShutDown.is_set(): try: InputMessage = DataS.get(GETBLOCK, GETTIMEOUT) except queue.Empty: continue except EOFError: ShutDown.set() break Message.Cut = InputMessage.Cut Message.Timestamp = InputMessage.Timestamp Message.Time_Interval = InputMessage.Time_Interval for n in InputMessage.nChannel: ch += 1 for f in Message._fields_: if i == ch: break if f[1] == ar_type: setattr(Message, f[0], np.ctypeslib.as_ctypes(InputMessage.nChannel[i])) i += 1 #for nc in InputMessage.nChannel: # Message.nChannel[i] = nc # i+=1 i = 0 ch = 0 try: Connection.sendall( premessage(PreMessage, Message.Cut, sizeof(Message))) Message.Timestamp = DOUBLE(datetime.utcnow().timestamp()) Connection.sendall( Message ) # Отправка преобразованных данных через протокол Sockets except socket.error as e: print(e) ShutDown.set() finally: Connection.close()
def file_mapping(sock, DataQ, DataS, ShutDown, LockQ): def _2sec(dvalue): return dvalue.timestamp() def datetime_fromdelphi(dvalue): return DELPHI_EPOCH + timedelta(days=dvalue) def readMem(mbuf, pos, bts, svpos, posret=True, bytesout=False, datetimedouble=False): size = sizeof(bts) bts_s = C.create_string_buffer(size) source = mbuf + pos length = SIZE_T(size) kernel32.RtlMoveMemory(bts_s, source, length) if svpos and posret: retpos = pos + size elif not svpos and posret: retpos = pos if bytesout: if posret: return np.array(bts_s, order='C').view(dtype=bts), retpos else: return np.array(bts_s, order='C').view(dtype=bts) elif datetimedouble: if posret: return (datetime_fromdelphi( C.cast(bts_s, POINTER(bts)).contents.value).timestamp(), retpos) else: return datetime_fromdelphi( C.cast(bts_s, POINTER(bts)).contents.value).timestamp() else: if posret: return C.cast(bts_s, POINTER(bts)).contents.value, retpos else: return C.cast(bts_s, POINTER(bts)).contents.value def _getMVData(mbuf, pos, data, create): tpos = pos def _dmvmapret(data): nonlocal mbuf nonlocal create nonlocal tpos buf = readMem(mbuf, tpos, FLOAT, False, posret=False, bytesout=True) tpos += SingleSize if create: return np.ndarray((1, ), buffer=buf, dtype=FLOAT, order='C') else: return np.concatenate( (data, np.ndarray( (1, ), buffer=buf, dtype=FLOAT, order='C')), axis=0) return list(map(_dmvmapret, data)), tpos def _OPret(data, datalen): def mapret(data): return data[-(datalen):, ] return list( map(mapret, data) ) # Выделение из общего массива считанных данных окна, равного CwtFreq while True: try: #hmap = kernel32.CreateFileMappingW(INVALID_HANDLE_VALUE, SA, PAGE_READWRITE, 0, EXPECTED_SIZE, TAGNAME) hmap = kernel32.OpenFileMappingW(FILE_MAP_ALL_ACCESS, False, TAGNAME) handle_nonzero_success(hmap) if hmap == INVALID_HANDLE_VALUE: kernel32.CloseHandle(hmap) raise Exception("Ошибка создания Filemapping") mbuf = kernel32.MapViewOfFile(hmap, FILE_MAP_ALL_ACCESS, 0, 0, EXPECTED_SIZE) break except WindowsError: print(C.WinError(C.get_last_error())) print( 'Перезапустите программу или запустите запись brainwin.exe...') time.sleep(5) continue tc = TChannel() while True: Freq, pos = readMem(mbuf, Int64Size * 3, INT64, True) # Частота оцифровки if Freq: break CwtFreq = int(Freq / DB) # Частота преобразования и отправки данных и длина окна print('\nЧастота оцифровки: ', Freq, 'Гц') Channels, pos = readMem( mbuf, pos, INT64, True) # Фактическое количество используемых каналов print('Количество каналов: ', Channels) sock.sendall( first_message(FIRST_MESSAGE_PAYLOAD(), Freq, CwtFreq, Channels)) # Сообщение серверу с первоначальными данными DataQ.put(Channels, PUTBLOCK, PUTTIMEOUT) LeadsAct = [0] * Channels LeadsPas = [0] * Channels Leads = [(0, 0)] * Channels for i in range(0, Channels): LeadsAct[i], pos = readMem(mbuf, pos, INT, True) cp = pos pos = (cp + IntegerSize * (ExpectedChannels - 1)) LeadsPas[i], pos = readMem(mbuf, pos, INT, False) pos = cp Leads[i] = (tc.leads[LeadsAct[i]], tc.leads[LeadsPas[i]]) print('Отведения: ', Leads) prepos1 = ((Int64Size * 5 + IntegerSize * ExpectedChannels * 2 + NameExpectedLength * AnsiCharSize)) prepos2 = ((DateTimeSize + Int64Size + SingleSize * ExpectedChannels)) Cut, pos = readMem(mbuf, Int64Size * 2, INT64, False) DataPayload = DATAMV_PAYLOAD() Datalen = 0 DataMV = [list()] * Channels FlushTime = True FlushMVData = True Flow = False cpr.SetPriority(5) slpt = 1 / Freq / 1000 try: while not ShutDown.is_set(): if not Flow: oldCut = Cut with LockQ: Cut = readMem(mbuf, Int64Size * 2, INT64, False, posret=False) acCut = Cut CwtCut = Cut + (SMOOTH + 50) if oldCut == Cut - 1: Flow = True print("Анализ...\n") else: time.sleep(slpt) continue else: acCut = readMem(mbuf, Int64Size * 2, INT64, False, posret=False) if acCut < oldCut: Flow = False Datalen = 0 continue """ with LockQ: mvCut, pos = readMem(mbuf, Int64Size+(prepos1+prepos2*(divmod(Cut, MaxData)[1])), INT64, False) """ if acCut > Cut: Cut += 1 else: time.sleep(slpt) continue Datalen += 1 # Чтение момента регистрации сигналов из общей памяти with LockQ: pos = prepos1 + prepos2 * (divmod(Cut, MaxData)[1]) AstrTime, pos = readMem(mbuf, pos, DOUBLE, True, bytesout=True) # # Чтение данных из общей памяти и конкатенация биосигнала в мкВ в массив типа Float if FlushMVData: FlushMVData = False with LockQ: DataMV, pos = _getMVData(mbuf, pos + Int64Size, DataMV, FlushMVData) # # Конкатенация времени в массив типа Double if FlushTime: CwtT = np.ndarray((1, ), buffer=AstrTime, dtype=DOUBLE, order='C') FlushTime = False else: CwtT = np.concatenate( (CwtT, np.ndarray( (1, ), buffer=AstrTime, dtype=DOUBLE, order='C')), axis=0) # # Отправка массива данных в очередь для дальнейшей обработки с окном, равным CwtFreq if Cut - CwtCut >= CwtFreq: if Datalen > CwtFreq: Datalen = CwtFreq CwtCut = Cut DataPayload.Cut = INT64(Cut) DataPayload.Data_Length = INT64(Datalen) DataPayload.nTimestamp = CwtT[-(Datalen + SMOOTH):, ] DataPayload.nChannel = _OPret(DataMV, Datalen + SMOOTH) DataQ.put(DataPayload, PUTBLOCK, PUTTIMEOUT) print('\nРазмер окна: ' + str(Datalen) + '\nСечение: ' + str(Cut)) Datalen = 0 # finally: print( '\n---------------------------------------------------------------\nАнализ окончен.' ) kernel32.CloseHandle(hmap) kernel32.UnmapViewOfFile(mbuf) while True: try: DataPayload = DataQ.get(GETBLOCK, GETTIMEOUT) except queue.Empty: continue except EOFError: break break WA = DataPayload.nWA print('Сохранение результатов!\n') timed = list( map( datetime_fromdelphi, CwtT[(SMOOTH_CUTRANGE + 50):(SMOOTH_CUTRANGE + 50) + len(WA[0])])) times = np.array(list(map(_2sec, timed))) times = times - np.min(times) for i in range(Channels): ar1 = (DataMV[i])[(SMOOTH_CUTRANGE + 50):(SMOOTH_CUTRANGE + 50) + len(WA[i])] ar2 = WA[i] plt.plot(times, ar1, linewidth=0.1) plt.plot(times, ar2, linewidth=0.4) plt.title("Результат анализа по каналу " + str(i + 1)) plt.ylabel("Измеренные значения и мощность, мкВ") plt.xlabel("Длительность, сек") plt.xticks() plt.savefig('Channel_' + str(i + 1) + '_cwt.svg') plt.clf() ar = np.vstack((timed, ar1)) ar = np.transpose(np.vstack((ar, ar2))) np.savetxt('Channel_' + str(i + 1) + '_cwt.csv', ar, header='Time,MV,CWT', delimiter=",", encoding='utf-8', fmt='%s') print('Сохранено: Канал ' + str(i + 1) + '!\n')
def analysis(DataQ, DataS, ShutDown, LockQ, Fltr): def getCwt(pool, data, dt, datalen): s0 = 2 * dt / EST_WAVELET.flambda() j = np.int(np.round(np.log2((datalen) * dt / s0) / DJ)) func = partial(mv2cwt, dt, s0, j, datalen, Fltr) return pool.map(func, data) Message = DATACWT_PAYLOAD() while not ShutDown.is_set(): # Чтение данных из очереди try: Channels = DataQ.get(GETBLOCK, GETTIMEOUT) break except queue.Empty: continue except EOFError: ShutDown.set() break # pool = Pool(processes=Channels) DataPayload = None cpr.SetPriority(1) WA = list() CwtD = [np.array([], dtype=DOUBLE, order='C')] * ExpectedChannels CwtCut = 1 FirstTime = True try: FlushCwt = True while not ShutDown.is_set(): # Чтение данных из очереди try: DataPayload = DataQ.get(GETBLOCK, GETTIMEOUT) except queue.Empty: continue except EOFError: ShutDown.set() break # # Отправка данных на анализ и преобразование #start = datetime.now() CwtDT = np.diff(DataPayload.nTimestamp).mean( ) # Вычисление интервала между точками CwtD = getCwt(pool, DataPayload.nChannel, CwtDT, DataPayload.Data_Length.value + SMOOTH) #print('Time spent '+str(datetime.now()-start)) # # if FirstTime: FirstTime = False DataS.put(DataPayload.Data_Length, PUTBLOCK, PUTTIMEOUT) # # Отправка данных в очередь на формирование пакета Sockets Message.Cut = INT64(CwtCut) Message.Datalen = DataPayload.Data_Length Message.Time_Interval = FLOAT(CwtDT) Message.nChannel = CwtD DataS.put(Message, PUTBLOCK, PUTTIMEOUT) # # if FlushCwt: WA = CwtD FlushCwt = False else: WA = np.concatenate((WA, CwtD), axis=1) CwtCut += 1 # finally: if DataPayload != None: DataPayload.nWA = WA DataQ.put(DataPayload, PUTBLOCK, PUTTIMEOUT) pool.close() pool.join()