add some .bin work, change name
This commit is contained in:
parent
333c475e0d
commit
1b2e2070f9
@ -79,7 +79,7 @@ class OBRData:
|
|||||||
metadata = fromfile(dtype=numpy.float64, offset=0x0c, count=4)
|
metadata = fromfile(dtype=numpy.float64, offset=0x0c, count=4)
|
||||||
ng = fromfile(dtype=numpy.float64, offset=0x2e, count=1)
|
ng = fromfile(dtype=numpy.float64, offset=0x2e, count=1)
|
||||||
gain_dB = fromfile(dtype=numpy.int16, offset=0x36, count=1)
|
gain_dB = fromfile(dtype=numpy.int16, offset=0x36, count=1)
|
||||||
dates = fromfile(dtype=numpy.int16, offset=0x46, count=2)
|
dates = fromfile(dtype=numpy.int16, offset=0x46, count=2 * 8)
|
||||||
t0half = fromfile(dtype=numpy.float64, offset=0x96, count=1)
|
t0half = fromfile(dtype=numpy.float64, offset=0x96, count=1)
|
||||||
freq_windowed = fromfile(dtype=numpy.int8, offset=0xb6, count=1).any()
|
freq_windowed = fromfile(dtype=numpy.int8, offset=0xb6, count=1).any()
|
||||||
arr = fromfile(dtype=numpy.float64, offset=0x800)
|
arr = fromfile(dtype=numpy.float64, offset=0x800)
|
||||||
@ -92,7 +92,6 @@ class OBRData:
|
|||||||
tm = arrs[2] + 1j * arrs[3]
|
tm = arrs[2] + 1j * arrs[3]
|
||||||
|
|
||||||
meas_date, calib_date = numpy.split(dates, 2)
|
meas_date, calib_date = numpy.split(dates, 2)
|
||||||
tt = numpy.arange(arrs[0].size) * dt_ns + t0half * 2
|
|
||||||
|
|
||||||
result = OBRData(
|
result = OBRData(
|
||||||
te = te,
|
te = te,
|
||||||
135
backwash/ova_bin.py
Normal file
135
backwash/ova_bin.py
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
from typing import IO, Self
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
import logging
|
||||||
|
import numpy
|
||||||
|
from numpy.typing import NDArray
|
||||||
|
from numpy.fft import fftshift, fftfreq
|
||||||
|
|
||||||
|
from .utils import C0
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class OVABINData:
|
||||||
|
te: NDArray[numpy.complex128] # time domain complex amplitude, polarization 1
|
||||||
|
tm: NDArray[numpy.complex128] # time domain complex amplitude, polarization 2
|
||||||
|
dt_ns: float # delta between time points
|
||||||
|
max_freq_GHz: float # sweep's max frequency (shortest wavelength)
|
||||||
|
ng_setting: float | None # set by user (for info only)
|
||||||
|
meas_date: NDArray[numpy.int16] # 8 items: year month [week?] day hour min sec ms
|
||||||
|
_wip_metadata: NDArray[numpy.float64] | None # unknown metadata values
|
||||||
|
|
||||||
|
@property
|
||||||
|
def time_ns(self) -> NDArray[numpy.float64]:
|
||||||
|
"""
|
||||||
|
Time delay (x-axis) for `te` and `tm` data
|
||||||
|
"""
|
||||||
|
tt = numpy.arange(self.tee.size) * self.dt_ns
|
||||||
|
return tt
|
||||||
|
|
||||||
|
@property
|
||||||
|
def wl_range_nm(self) -> NDArray[numpy.float64]:
|
||||||
|
freq_range = numpy.asarray([
|
||||||
|
self.max_freq_GHz - 1 / (2 * self.dt_ns),
|
||||||
|
welf.max_freq_GHz,
|
||||||
|
])
|
||||||
|
return C0 / freq_range
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ctr_freq_GHz(self) -> float:
|
||||||
|
return self.max_freq_GHz - 1 / (4 * self.dt_ns)
|
||||||
|
|
||||||
|
def freqs(self, size: int) -> NDArray[numpy.float64]:
|
||||||
|
# To be used with spectrum generated with e.g. fft(fftshift(data.te))
|
||||||
|
frq_GHz = fftshift(fftfreq(size, d=self.dt_ns)) + self.ctr_freq_GHz
|
||||||
|
return frq_GHz
|
||||||
|
|
||||||
|
def wls(self, size: int) -> NDArray[numpy.float64]:
|
||||||
|
# To be used with spectrum generated with e.g. fft(fftshift(data.te))
|
||||||
|
return C0 / self.freqs(size)
|
||||||
|
|
||||||
|
def window(self, size: int) -> NDArray[numpy.float64]:
|
||||||
|
# Approximation of the generalized Hamming window used when freq_windowed==True
|
||||||
|
nn = numpy.linspace(0, 1, size)
|
||||||
|
alpha = 0.572
|
||||||
|
scale = 1.5 # likely related to "incoherent power gain compensation" for Hamming window (=1.54)
|
||||||
|
# 1.50 seems to fit the data better though
|
||||||
|
ham = alpha - (1 - alpha) * numpy.cos(2 * numpy.pi * nn)
|
||||||
|
return scale * ham
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def read(file: str | IO[bytes] | Path) -> Self:
|
||||||
|
raise NotImplementedError('Still WIP')
|
||||||
|
def fromfile(*args, **kwargs) -> NDArray:
|
||||||
|
if not isinstance(file, str | Path):
|
||||||
|
file.seek(0)
|
||||||
|
return numpy.fromfile(file, *args, **kwargs)
|
||||||
|
|
||||||
|
magic = fromfile(dtype=numpy.uint8, offset=0x10, count=7)
|
||||||
|
if (magic != [0x40] + [ord(cc) for cc in 'S33OVA']).any():
|
||||||
|
logger.warning(f'Unexpected magic bytes: {magic}')
|
||||||
|
|
||||||
|
metadata = fromfile(dtype=numpy.float64, offset=0x00, count=2)
|
||||||
|
meas_date = fromfile(dtype=numpy.int16, offset=0x49, count=8)
|
||||||
|
|
||||||
|
wl_range = fromfile(dtype=numpy.int32, offset=0x17, count=1)
|
||||||
|
data_len = 4 * wl_range
|
||||||
|
arr = fromfile(dtype=numpy.float64, offset=0x59, count=data_len)
|
||||||
|
ng = fromfile(dtype=numpy.float32, offset=0x21, count=1)
|
||||||
|
|
||||||
|
max_freq_GHz = metadata[0]
|
||||||
|
#dt_ns = metadata[3] / 2
|
||||||
|
|
||||||
|
arrs = numpy.split(arr, 4)
|
||||||
|
te = arrs[0] + 1j * arrs[1]
|
||||||
|
tm = arrs[2] + 1j * arrs[3]
|
||||||
|
|
||||||
|
result = OVABINData(
|
||||||
|
te = te,
|
||||||
|
tm = tm,
|
||||||
|
#dt_ns = dt_ns,
|
||||||
|
max_freq_GHz = max_freq_GHz,
|
||||||
|
ng_setting = ng,
|
||||||
|
meas_date = meas_date,
|
||||||
|
_wip_metadata = metadata[1:],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Notes on .bin file format (OVA)
|
||||||
|
================================
|
||||||
|
|
||||||
|
0x00: 9D A8 5A 6B C8 D0 0C 41 13 23 63 4D 22 74 C4 3F
|
||||||
|
|max_freq_GHZ (f64)------ | f64 ??----------------- |
|
||||||
|
C0/freq = wl_nm 5.848e6 ~> 51.3nm if GHz
|
||||||
|
could be dt in ps?
|
||||||
|
|
||||||
|
0x10: 40 53 33 33 4F 56 41 00 00 00 01 00 00 00 00 00
|
||||||
|
| S 3 3 | O V A | wl range |
|
||||||
|
1 = biggest range (58.97nm), others are exponents of 2 smaller (resolution)
|
||||||
|
effectively length of each sub-array (x 4 arrays)
|
||||||
|
|
||||||
|
0x20: 00 00 80 20 40 01 00 00 00 00 00 00 00 00 00 00
|
||||||
|
| ng (f32) |----........|
|
||||||
|
??? average count
|
||||||
|
|
||||||
|
0x30: 00 00 00 00 00 00 38 98 40 00 00 00 00 00 00 00
|
||||||
|
???????????
|
||||||
|
|
||||||
|
0x40: 00 00 00 00 00 00 00 00 00 E7 07 0A 00 05 00 06
|
||||||
|
|year month week? day-
|
||||||
|
acquisition timestamp
|
||||||
|
|
||||||
|
0x50: 00 12 00 0F 00 0F 00 23 00 F7 27 6F E5 17 A1 A7
|
||||||
|
--- hr minute sec ms | f64 data starts----
|
||||||
|
(offset 0x59)
|
||||||
|
|
||||||
|
0x400040:
|
||||||
|
3F C8 E2 3E 89 8A A4 8C BF A9 4D A8 8A D6 9B 94
|
||||||
|
0x400050:
|
||||||
|
3F 8E BB 79 0C C2 84 92 3F 4E 4F 4E 45 40
|
||||||
|
|N O N E |
|
||||||
|
"""
|
||||||
@ -1,5 +1,5 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "blowback"
|
name = "backwash"
|
||||||
description = "Optical reflectometry file format reader"
|
description = "Optical reflectometry file format reader"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = { file = "LICENSE.md" }
|
license = { file = "LICENSE.md" }
|
||||||
@ -39,7 +39,7 @@ dependencies = [
|
|||||||
"numpy>=1.26",
|
"numpy>=1.26",
|
||||||
]
|
]
|
||||||
[tool.hatch.version]
|
[tool.hatch.version]
|
||||||
path = "blowback/__init__.py"
|
path = "backwash/__init__.py"
|
||||||
|
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user