Análisis de datos de osciloscopio, seguimiento -- python campo con parsing campo con python-2.x campo con file-structure camp codereview Relacionados El problema

Parsing oscilloscope data, follow up


2
vote

problema

Español

Seguimiento de seguimiento en analizando los datos binarios del osciloscopio . Escribí un parser simple para el formato de archivo interno de Tektronix .isf . Revisé mi código a lo siguiente:

  import numpy as np import os.path   def parse_curve(isf_file):     """     Reads one tektronix .isf file and returns a dictionary containing     all tags as keys. The actual data is stored in the key "data".     """     extensions = set([".isf"])     if os.path.splitext(isf_file)[-1].lower() not in extensions:         raise ValueError("File type unkown.")      with open(isf_file, 'rb') as ifile:         # read header         header = {}         while True:             name = _read_chunk(ifile, " ")             if name != ":CURVE":                 value = _read_chunk(ifile, ";")                  assert name not in header                 header[name] = value             else:                 # ":CURVE " is the last tag of the header, followed by                 # '#XYYY' with X being the number of bytes of YYY.                 # YYY is the length of the datastream following in bytes.                 value = ifile.read(2)                 y_str = ifile.read(int(value[-1]))                 value += y_str                  # the number of bytes might be present with or without the                 # preceding header ":WFMPRE:"                 nobytes = header.get("BYT_NR",                                      header.get(":WFMPRE:BYT_NR", "0")                                      )                 assert int(y_str) == int(header["NR_PT"]) * int(nobytes)                 header[name] = value                 currentposition = ifile.tell()                 break          assert header["ENCDG"] == "BINARY"          # read data as numpy array         header["data"] = _read_data(ifile, currentposition, header)      return header   def _read_chunk(headerfile, delimiter):     """     Reads one chunk of header data. Based on delimiter, this may be a tag     (ended by " ") or the value of a tag (ended by ";").     """     prior_delimiter = None     chunk = []     while True:         c = headerfile.read(1)         if c != delimiter:             chunk.append(c)             if c == '"':                 # switch delimiter to make sure to parse the whole string                 # enclosed in '"'.                 delimiter, prior_delimiter = c, delimiter         elif prior_delimiter:             # switch back delimiter             chunk.append(c)             delimiter, prior_delimiter = prior_delimiter, None         else:             return "".join(chunk)   def _read_data(bfile, position, header):     """     Reads in the binary data as numpy array.     Apparently, there are only 1d-signals stored in .isf files, so a 1d-array     is read.     """     # determine the datatype from header tags     datatype = ">" if header["BYT_OR"] == "MSB" else "<"     if header["BN_FMT"] == "RI":         datatype += "i"     else:         datatype += "u"     # BYT_NR might be present with preceding header ":WFMPRE:BYT_NR"     nobytes = header.get("BYT_NR",                          header.get(":WFMPRE:BYT_NR", "")                          )     datatype += nobytes     assert len(datatype) >= 3      bfile.seek(position)     data = np.fromfile(bfile, datatype)     assert data.size == int(header["NR_PT"])      # calculate true values     data = data * float(header["YMULT"]) + float(header["YZERO"])      return data   

En la pregunta original, _read_data hizo un poco más, esta parte ahora se trasladó a otro módulo.

Una preocupación que todavía tengo, es si la parte 99887777655544335 al leer la etiqueta ": curva" es la mejor solución:

  nobytes = header.get("BYT_NR",                      header.get(":WFMPRE:BYT_NR", "0")                      ) assert int(y_str) == int(header["NR_PT"]) * int(nobytes)   
Original en ingles

Follow-up up on Parsing oscilloscope binary data. I wrote a simple parser for Tektronix's internal file format .isf. I revised my code to the following:

import numpy as np import os.path   def parse_curve(isf_file):     """     Reads one tektronix .isf file and returns a dictionary containing     all tags as keys. The actual data is stored in the key "data".     """     extensions = set([".isf"])     if os.path.splitext(isf_file)[-1].lower() not in extensions:         raise ValueError("File type unkown.")      with open(isf_file, 'rb') as ifile:         # read header         header = {}         while True:             name = _read_chunk(ifile, " ")             if name != ":CURVE":                 value = _read_chunk(ifile, ";")                  assert name not in header                 header[name] = value             else:                 # ":CURVE " is the last tag of the header, followed by                 # '#XYYY' with X being the number of bytes of YYY.                 # YYY is the length of the datastream following in bytes.                 value = ifile.read(2)                 y_str = ifile.read(int(value[-1]))                 value += y_str                  # the number of bytes might be present with or without the                 # preceding header ":WFMPRE:"                 nobytes = header.get("BYT_NR",                                      header.get(":WFMPRE:BYT_NR", "0")                                      )                 assert int(y_str) == int(header["NR_PT"]) * int(nobytes)                 header[name] = value                 currentposition = ifile.tell()                 break          assert header["ENCDG"] == "BINARY"          # read data as numpy array         header["data"] = _read_data(ifile, currentposition, header)      return header   def _read_chunk(headerfile, delimiter):     """     Reads one chunk of header data. Based on delimiter, this may be a tag     (ended by " ") or the value of a tag (ended by ";").     """     prior_delimiter = None     chunk = []     while True:         c = headerfile.read(1)         if c != delimiter:             chunk.append(c)             if c == '"':                 # switch delimiter to make sure to parse the whole string                 # enclosed in '"'.                 delimiter, prior_delimiter = c, delimiter         elif prior_delimiter:             # switch back delimiter             chunk.append(c)             delimiter, prior_delimiter = prior_delimiter, None         else:             return "".join(chunk)   def _read_data(bfile, position, header):     """     Reads in the binary data as numpy array.     Apparently, there are only 1d-signals stored in .isf files, so a 1d-array     is read.     """     # determine the datatype from header tags     datatype = ">" if header["BYT_OR"] == "MSB" else "<"     if header["BN_FMT"] == "RI":         datatype += "i"     else:         datatype += "u"     # BYT_NR might be present with preceding header ":WFMPRE:BYT_NR"     nobytes = header.get("BYT_NR",                          header.get(":WFMPRE:BYT_NR", "")                          )     datatype += nobytes     assert len(datatype) >= 3      bfile.seek(position)     data = np.fromfile(bfile, datatype)     assert data.size == int(header["NR_PT"])      # calculate true values     data = data * float(header["YMULT"]) + float(header["YZERO"])      return data 

In the original question, _read_data did a little more, this part was now moved to another module.

One concern I still have, is whether the assert part when reading the ":CURVE" tag is the best solution:

nobytes = header.get("BYT_NR",                      header.get(":WFMPRE:BYT_NR", "0")                      ) assert int(y_str) == int(header["NR_PT"]) * int(nobytes) 
           

Lista de respuestas

1
 
vote

En general, se ve bien conmigo; Solo pequeñas liendres:

Desea pasar de afligidos a lanzar excepciones propias e informativas, por ejemplo, que muestran valores esperados y reales.

Al final de if name != ":CURVE": , puede emitir un bloqueo 99887766655443399 visited0 ayuda con la sangría.

En lugar de hacer visited1 una lista y luego hacer un 99887776655443312 al final, puede hacerlo una cadena y hacer una cadena anexar.

 

In general it looks good to me; only small nits:

You want to move from asserts to throwing proper, informative exceptions - for instance, showing both expected and actual values.

At the end of if name != ":CURVE":, you can just issue a continue instead of an else block - helps with the indentation.

Instead of making chunk a list and then doing a join at the end, you can make it a string and do string appending.

 
 
 
 

Relacionados problema

7  Analizar un archivo WAV y exportar datos PCM  ( Parse a wav file and export pcm data ) 
Soy Newbie y yo escribimos un código que obtiene un archivo WAV y exporta un archivo RAW (solo PCM) a * .Raw Archivo. Pero estoy confundido acerca de la estru...

0  Script de Analytics Ad-Hoc al módulo / Paquete  ( Ad hoc analytics script to module package ) 
Tengo un proceso de análisis de texto que complete para trabajar. Este proceso minas texto para diferentes cuentas de Twitter y encuentra patrones en los Twee...

4  C Programa que recupera los archivos JPEG perdidos  ( C program that recovers lost jpeg files ) 
Mi estrategia general es cargar un tamaño de bloque (512bytes) en la memoria y verifique si los bloques de los primeros 4 bytes coinciden con los primeros 4 b...

4  Actualizando los registros de archivos de datos  ( Updating data file records ) 
Aprendí a codificar un largo, hace mucho tiempo. preocupaciones El enfoque existente es desordenado y será difícil de mantener. Los errores del sistema ...

4  Leer dimensiones JPEG correctamente  ( Read jpeg dimensions properly ) 
Necesito extraer las dimensiones (ancho y altura) de un archivo JPEG para insertar en un documento HTML. Según el Preguntas frecuentes de compresión de imáge...

9  Lectura de archivos binarios en formato XTF  ( Reading binary files in xtf format ) 
Tengo algunos miles de archivos binarios que tienen estructuras correspondientes en ellos, seguidas de cualquier número de bytes (este número exacto de bytes ...

11  Código para llenar la tabla de direcciones de importación PE  ( Code to fill pe import address table ) 
Escribí un programa para probar los motores AV contra el cifrado. Cuando se ejecuta, calculará alguna clave, descifrará un ejecutable que tiene en su sección ...

2  Reemplace la primera aparición de patrón en el archivo  ( Replace first occurrence of pattern in file ) 
Aquí está mi intento de reemplazar la primera ocurrencia de pattern en el archivo con espacios. La eliminación efectiva, y con suerte me permita "eliminarlo...

2  Parse la información de unión de Mach-O  ( Parse mach o binding info ) 
Escribí este programa C para abrir un ejecutable / marco de Mach-O y analizar los símbolos externos junto con su marco / biblioteca respectivos. Algunas cosas...

7  Generador de archivos de prueba binaria con suma de comprobación  ( Binary test file generator with checksum ) 
en la lectura Esta pregunta , se me ocurrió que sería útil crear archivos de prueba de acuerdo con la especificación del formato de archivo. Para recubrir, e...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos