Чтение данных из файла.hpf

Я использую Quickdaq получать данные от моего датчика; выход является .hpf файл

Я хочу прочитать данные из этого файла в python & matplotlib применить некоторый анализ сигналов.

Как я могу читать (или конвертировать в .csv) .hpf файл с питоном (или любым другим языком)?

Я нашел это в Интернете, но я не знаю, как его использовать, если это последнее решение?

2 ответа

Я предполагаю, что это немного устарело для исходного плаката, однако, если у кого-то еще возникнет эта проблема, я только что написал сценарий для извлечения информации и данных из этих файлов, однако он тестируется только на данных одного канала, я нет многоканальных данных для тестирования.

https://github.com/jogrundy/Read_QuickDAQ_.hpf

Это началось как перевод кода MATLAB с https://www.datatranslation.de/Download/Demos/Hpf2Matlab_Rev2_0.m

Надеюсь это поможет.

Разработчики программного обеспечения QuickDAQ, похоже, предоставили решение, см. Этот скрипт Python в разделе загрузок на домашней странице QuickDAQ .

Точные спецификации для .hpfТип файла предоставлен компанией Data Translation по этой ссылке в формате pdf .

В случае, если ссылка на скрипт python в будущем станет неработоспособной, скрипт преобразования, написанный Майклом Бюргином, воспроизводится ниже.

      ###########################################################################
# 
# Author:       Measurement Computing GmbH
#               Michael Buergin
    
# Date:         02.11.2017
    
# Version:      1.0
    
# Description:  
# Python Converter for Data Translation's HPF-file format.
# Can convert a single file or a complete directory

# REMARKS:
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
    
# Changes: --
#
#
# ConvertHPFData_Folder
# Input Parameter :
# folder_in = Complete path to the folder with HPF-file
# folder_out = Complete path to store ASCII-files (if None; new "ASCII"-folder is created in folder_in)
# suppress_print = suppress print of hpf-file-data
#
# WARNING: existing txt-files will be overwritten!
#
# ConvertHPFData
# Input Parameter :
# InputFile = Complete path to the input HPF-file.
# OutputFile = Complete path to the output ASCII-file.
# SelectedChannel = Channel to read from the HPF-file. 1 as first channel.
# suppress_print = suppress print of hpf-file-data
    
# Output Data:
# ReturnData = Matrix with all Data for the selected channel
# OutputFile = ASCII-file with all Data for the selected channel
    
    ###########################################################################

import numpy as np
import struct
import os

def ConvertHPFData_Folder(folder_in=None, folder_out=None, suppress_print=True, SelectedChannel=None):
    if folder_out == None: folder_out=folder_in + '\\ASCII'
    all_hpf_files = [fn for fn in os.listdir(folder_in)
                     if any(fn.endswith(ext) for ext in 'hfp')]

    if not os.path.isdir(folder_out): os.mkdir(folder_out)
    i_file = 1
    for file in all_hpf_files:
        ConvertHPFData(SelectedChannel='all',
                       InputFile=folder_in+'\\'+file,
                       OutputFile=folder_out+'\\'+file[:-3]+'txt',
                       suppress_print=suppress_print)
        print('last file: %s (%i/%i)' % (file, i_file, len(all_hpf_files)))
        i_file +=1

    print('all done :)')

def ConvertHPFData(InputFile=None,OutputFile=None,SelectedChannel=None,suppress_print=False):

    if not suppress_print: print('-- Start')
    ReturnData=[]

    with open(InputFile, mode='rb') as in_file:  # b -> binary
        fileContent = in_file.read()

    if OutputFile!=None: out_file = open(OutputFile, 'w')

    if SelectedChannel == 'all':
        SelectedChannelAll = 1
        ChannelError = False
        while ChannelError == False:
            [result_tmp, result_name_tmp, ChannelError] = ReadHPFData(SelectedChannel=SelectedChannelAll,
                                                                      fileContent=fileContent,
                                                                      out_file=out_file,
                                                                      OutputFile=OutputFile,
                                                                      AllCh=True,
                                                                      suppress_print=True)
            if ChannelError == False:
                if SelectedChannelAll==1:
                    ReturnData = result_tmp
                    Result_Name = [result_name_tmp]
                else:
                    ReturnData = np.append(np.array(ReturnData), np.array([result_tmp[1,:]]), axis=0)
                    Result_Name.append(result_name_tmp)
                    if not suppress_print: print(Result_Name)
            SelectedChannelAll += 1
    else:
        [ReturnData, Result_Name, ChannelError] = ReadHPFData(SelectedChannel=SelectedChannel,
                                                              fileContent=fileContent,
                                                              out_file=out_file,
                                                              OutputFile=OutputFile,
                                                              AllCh=False)
        Result_Name = [Result_Name]


    in_file.close()

    if OutputFile!=None:
        if SelectedChannel != 'all' and ChannelError: out_file.close()
        else:
            out_file.write('time\t')
            for i_channel in range(len(Result_Name)):
                out_file.write(Result_Name[i_channel]+'\t')
            out_file.write('\n')
            for i_ReturnData in range(len(ReturnData[0, :])):
                for i_channel in range(len(ReturnData[:, 0])):
                    out_file.write(('%f\t') % (ReturnData[i_channel, i_ReturnData]))
                out_file.write('\n')
            out_file.close()

    if not suppress_print: print('-- Finish')
    return ReturnData

def char_tuple_2_str(tuple):
    string = ""
    for chars in tuple:
        string = string + chars.decode('utf-8')
    return string

def find_all_str(string,sub):
    index = string.find(sub)
    if index == -1: return [-1]
    indices = [index]
    while True:
        index = string.find(sub, index+1)
        if index == -1: return indices
        indices.append(index)

    return indices

def ReadHPFData(SelectedChannel=None,fileContent=None, out_file=None, OutputFile=None, AllCh=None, suppress_print=False):

    if AllCh and SelectedChannel == 1:
        flag_write = True
    else:
        flag_write = False

    ReturnData=[]
    pos = 0
    off = 0
    i_line = 0

    while i_line <= len(fileContent) - 1:

        in_chunkID = struct.unpack('q', fileContent[i_line:i_line + 8])[0];
        i_line = i_line + 8
        off = struct.unpack('q', fileContent[i_line:i_line + 8])[0];
        i_line = i_line + 8

        if i_line == len(fileContent) or off == 0:
            break

        if 4096 == in_chunkID:
            if not suppress_print: print('- Parsing Header Chunk')
            in_ChratorID = char_tuple_2_str(struct.unpack('c' * 4, fileContent[i_line:i_line + 4]));
            i_line = i_line + 4
            in_fileVersion = struct.unpack('q', fileContent[i_line:i_line + 8])[0];
            i_line = i_line + 8
            in_indexChunkOffset = struct.unpack('q', fileContent[i_line:i_line + 8])[0];
            i_line = i_line + 8
            len_in_XMLdata = off - (i_line - pos)
            in_XMLdata = char_tuple_2_str(
                struct.unpack('c' * len_in_XMLdata, fileContent[i_line:i_line + len_in_XMLdata]));
            i_line = i_line + len_in_XMLdata
            start = in_XMLdata.find('<RecordingDate>')
            stop = in_XMLdata.find('</RecordingDate>')
            Information = in_XMLdata[start + 15:stop - 1]
            if not suppress_print: print('RecordingDate: ' + Information)
            if OutputFile != None and flag_write: out_file.write('RecordingDate: ' + Information + '\n')
            Result_RecordingDate = Information
        else:
            if 8192 == in_chunkID:
                if not suppress_print: print('- Parsing Channel Information Chunk')
                in_groupID = struct.unpack('l', fileContent[i_line:i_line + 4])[0];
                i_line = i_line + 4
                in_numberOfChannals = struct.unpack('l', fileContent[i_line:i_line + 4])[0];
                i_line = i_line + 4
                len_in_XMLdata = off - (i_line - pos)
                in_XMLdata = char_tuple_2_str(
                    struct.unpack('c' * len_in_XMLdata, fileContent[i_line:i_line + len_in_XMLdata]));
                i_line = i_line + len_in_XMLdata
                start = find_all_str(in_XMLdata, ('<Name>'))
                stop = find_all_str(in_XMLdata, ('</Name>'))
                if len(start) < SelectedChannel or SelectedChannel<=0:
                    if AllCh == False:
                        if not suppress_print: print('\nWrong channel selected!')
                        if not suppress_print: print('\npossible channels: %i ... %i' % (1, len(start)))
                        if OutputFile != None:
                            out_file.write('\nWrong channel selected!')
                            out_file.write('\npossible channels: %i ... %i' % (1, len(start)))
                    return 0, 0, True

                if OutputFile != None: out_file.write('Total Channel: ' + str(len(start)) + '\n')
                if not suppress_print: print('Total Channel: ', str(len(start)))
                Ch_offset = np.zeros(len(start))
                Ch_length = np.zeros(len(start))

                # Store Channel in return struct
                Result_Channel = SelectedChannel
                if not suppress_print: print('Selected Channel Information:')
                if OutputFile != None: out_file.write('Selected Channel Information:\n')
                Information = in_XMLdata[start[SelectedChannel - 1] + 6:stop[SelectedChannel - 1]]
                if not suppress_print: print('Name: ', Information)
                if OutputFile != None: out_file.write('Name: ' + Information + '\n')
                Result_Name = Information

                start = find_all_str(in_XMLdata, ('<Unit>'))
                stop = find_all_str(in_XMLdata, ('</Unit>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 6:stop[SelectedChannel - 1]]
                if not suppress_print: print('Unit: ', Information)
                if OutputFile != None: out_file.write('Unit: ' + Information + '\n')
                Result_Unit = Information

                start = find_all_str(in_XMLdata, ('<ChannelType>'))
                stop = find_all_str(in_XMLdata, ('</ChannelType>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 13:stop[SelectedChannel - 1]]
                if not suppress_print: print('ChannelType: ', Information)
                if OutputFile != None: out_file.write('ChannelType: ' + Information + '\n')
                Result_ChannelType = Information

                start = find_all_str(in_XMLdata, ('<AssignedTimeChannelIndex>'))
                stop = find_all_str(in_XMLdata, ('</AssignedTimeChannelIndex>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 26:stop[SelectedChannel - 1]]
                if not suppress_print: print('AssignedTimeChannelIndex: ', Information)
                if OutputFile != None: out_file.write('AssignedTimeChannelIndex: ' + Information + '\n')
                Result_AssignedTimeChannelIndex = Information

                start = find_all_str(in_XMLdata, ('<DataType>'))
                stop = find_all_str(in_XMLdata, ('</DataType>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 10:stop[SelectedChannel - 1]]
                if not suppress_print: print('DataType: ', Information)
                if OutputFile != None: out_file.write('DataType: ' + Information + '\n')
                Result_DataType = Information

                start = find_all_str(in_XMLdata, ('<DataIndex>'))
                stop = find_all_str(in_XMLdata, ('</DataIndex>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 11:stop[SelectedChannel - 1]]
                if not suppress_print: print('DataIndex: ', Information)
                if OutputFile != None: out_file.write('DataIndex: ' + Information + '\n')
                Result_DataIndex = float(Information)

                start = find_all_str(in_XMLdata, ('<StartTime>'))
                stop = find_all_str(in_XMLdata, ('</StartTime>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 11:stop[SelectedChannel - 1]]
                if not suppress_print: print('StartTime: ', Information)
                if OutputFile != None: out_file.write('StartTime: ' + Information + '\n')
                Result_StartTime = Information

                start = find_all_str(in_XMLdata, ('<TimeIncrement>'))
                stop = find_all_str(in_XMLdata, ('</TimeIncrement>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 15:stop[SelectedChannel - 1]]
                if not suppress_print: print('TimeIncrement: ', Information)
                if OutputFile != None: out_file.write('TimeIncrement: ' + Information + '\n')
                Result_TimeIncrement = float(Information)

                start = find_all_str(in_XMLdata, ('<RangeMin>'))
                stop = find_all_str(in_XMLdata, ('</RangeMin>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 10:stop[SelectedChannel - 1]]
                if not suppress_print: print('RangeMin: ', Information)
                if OutputFile != None: out_file.write('RangeMin: ' + Information + '\n')
                Result_RangeMin = float(Information)

                start = find_all_str(in_XMLdata, ('<RangeMax>'))
                stop = find_all_str(in_XMLdata, ('</RangeMax>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 10:stop[SelectedChannel - 1]]
                if not suppress_print: print('RangeMax: ', Information)
                if OutputFile != None: out_file.write('RangeMax: ' + Information + '\n')
                Result_RangeMax = float(Information)

                start = find_all_str(in_XMLdata, ('<DataScale>'))
                stop = find_all_str(in_XMLdata, ('</DataScale>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 11:stop[SelectedChannel - 1]]
                if not suppress_print: print('DataScale: ', Information)
                if OutputFile != None: out_file.write('DataScale: ' + Information + '\n')
                Result_DataScale = float(Information)

                start = find_all_str(in_XMLdata, ('<DataOffset>'))
                stop = find_all_str(in_XMLdata, ('</DataOffset>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 12:stop[SelectedChannel - 1]]
                if not suppress_print: print('DataOffset: ', Information)
                if OutputFile != None: out_file.write('DataOffset: ' + Information + '\n')
                Result_DataOffset = float(Information)

                start = find_all_str(in_XMLdata, ('<SensorScale>'))
                stop = find_all_str(in_XMLdata, ('</SensorScale>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 13:stop[SelectedChannel - 1]]
                Sens_Scale = Information
                if not suppress_print: print('SensorScale: ', Information)
                if OutputFile != None: out_file.write('SensorScale: ' + Information + '\n')
                Result_SensorScale = float(Sens_Scale)

                start = find_all_str(in_XMLdata, ('<SensorOffset>'))
                stop = find_all_str(in_XMLdata, ('</SensorOffset>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 14:stop[SelectedChannel - 1]]
                SensorOffset = Information
                if not suppress_print: print('SensorOffset: ', Information)
                if OutputFile != None: out_file.write('SensorOffset: ' + Information + '\n')
                Result_SensorOffset = float(SensorOffset)

                start = find_all_str(in_XMLdata, ('<PerChannelSampleRate>'))
                stop = find_all_str(in_XMLdata, ('</PerChannelSampleRate>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 22:stop[SelectedChannel - 1]]
                if not suppress_print: print('PerChannelSampleRate: ', Information)
                if OutputFile != None: out_file.write('PerChannelSampleRate: ' + Information + '\n')
                Result_PerChannelSampleRate = Information

                start = find_all_str(in_XMLdata, ('<PhysicalChannelNumber>'))
                stop = find_all_str(in_XMLdata, ('</PhysicalChannelNumber>'))
                Information = in_XMLdata[start[SelectedChannel - 1] + 23:stop[SelectedChannel - 1]]
                if not suppress_print: print('PhysicalChannelNumber: ', Information)
                if OutputFile != None: out_file.write('PhysicalChannelNumber: ' + Information + '\n\n')
                Result_PhysicalChannelNumber = Information
            else:
                if 12288 == in_chunkID:
                    if not suppress_print: print('- Parsing Data Chunk')
                    in_chunksize = off
                    in_groupID = struct.unpack('l', fileContent[i_line:i_line + 4])[0];
                    i_line = i_line + 4
                    in_dataStartIndex = struct.unpack('q', fileContent[i_line:i_line + 8])[0];
                    i_line = i_line + 8
                    in_chanalDataCount = struct.unpack('l', fileContent[i_line:i_line + 4])[0];
                    i_line = i_line + 4
                    for count in range(in_chanalDataCount):
                        if count + 1 == (SelectedChannel):
                            Ch_offset[count] = int(struct.unpack('l', fileContent[i_line:i_line + 4])[0]);
                            i_line = i_line + 4
                            Ch_length[count] = int(struct.unpack('l', fileContent[i_line:i_line + 4])[0]);
                            i_line = i_line + 4
                        else:
                            i_line = i_line + 8
                    ignoreCount = 0
                    for count in range(in_chanalDataCount):
                        if count + 1 == (SelectedChannel):
                            divider = 8
                            i_line = i_line + int(Ch_offset[count]) - int(32 + (in_chanalDataCount * 8))
                            tmpData = list(struct.unpack('d' * int(Ch_length[count] / divider),
                                                         fileContent[int(i_line):int(i_line + Ch_length[count])]));
                            i_line = i_line + int(Ch_length[count])
                            # Append Data
                            ReturnData.extend(tmpData)
                        else:
                            ignoreCount = ignoreCount + 1
                else:
                    if 28672 == in_chunkID:
                        if not suppress_print: print('- Parsing Undocumented Part')
                        i_line = i_line + 8
        Position = off - (i_line - pos)
        i_line = i_line + Position
        pos = i_line
    ReturnData = np.array(ReturnData) * Result_SensorScale + Result_SensorOffset

    Result_Time = np.array(float(Result_TimeIncrement)*(np.array(range(0,len(ReturnData)))))
    ReturnData = np.append([Result_Time], [ReturnData], axis=0)

    return ReturnData, Result_Name, False

if __name__ == '__main__':
    ConvertHPFData_Folder(folder_in=r"C:\Users\mbuergin\AppData\Local\Data Translation\QuickDAQ\Data",
                          folder_out=r"C:\Users\mbuergin\AppData\Local\Data Translation\QuickDAQ\Data",
                          SelectedChannel='all')

    
Другие вопросы по тегам