ars_noise_measurement/norsonic_parser.py

63 lines
1.7 KiB
Python

from dataclasses import dataclass
CRLF = '\r\n'
COL_SEPARATOR = '\t'
FFT_TOP_FREQ = 21996.1
@dataclass
class NorsonicReportData:
profile: list[dict[str, str]]
glob_funcs: dict[str, str]
glob_fft: dict[float, float]
def parse_report_table(table: str):
_, head_cols, *rows = table.split(CRLF)
cols = head_cols.split(COL_SEPARATOR)
def parse_row(row: str):
vals = row.split(COL_SEPARATOR)
if len(vals) != len(cols):
print(vals)
print(cols)
print(len(cols))
print(len(vals))
raise ValueError('NorParser: Invalid row read')
return {cols[i]: vals[i] for i in range(len(cols))}
return [parse_row(r) for r in rows if len(r) > 0]
def parse_glob(table: str) -> tuple[dict[str, str], dict[float, float]]:
_, head_cols, row = table.split(CRLF)
cols = head_cols.split(COL_SEPARATOR) [:-1]
vals = row.split(COL_SEPARATOR)
functions = {cols[i]: vals[i] for i in range(len(cols))}
fft_vals = list(map(float, vals[len(cols):]))
fft_points = len(fft_vals)
fft_freqs = [FFT_TOP_FREQ * (i+1)/(fft_points + 1) for i in range(fft_points)]
fft = {freq: val for freq, val in zip(fft_freqs, fft_vals)}
return functions, fft
def parse_report(report: bytes):
*header, glob, prof = report.decode().split(2*CRLF)
t_prof = parse_report_table(prof)
t_glob, fft = parse_glob(glob)
# t_glob = parse_report_table(glob)
# return t_glob, t_prof
return NorsonicReportData(t_prof, t_glob, fft)
# return t_prof
if __name__ == '__main__':
FNAME = '/home/Downloads/VIP 688 2025-02-05 13-40-36.txt'
CRLF = '\n'
with open(FNAME, 'rb') as f:
rb = f.read()
global ret
ret = parse_report(rb)