Source code for ooragan.util

import numpy as np
import pandas as pd
import re

from datetime import datetime
from numpy.typing import NDArray, ArrayLike


[docs] def str_to_time(time_string: str) -> float: """ Converts the time format from the MeaVis' HDF5 files into a datetime timestamp. Parameters ---------- time_string : str Timestamp string from MeaVis. """ fields = dict(re.findall(r"(tm_\w+)=(-?\d+)", time_string)) dt = datetime( year=int(fields["tm_year"]), month=int(fields["tm_mon"]), day=int(fields["tm_mday"]), hour=int(fields["tm_hour"]), minute=int(fields["tm_min"]), second=int(fields["tm_sec"]), ) return dt.timestamp()
[docs] def convert_magphase_to_complex( mag: NDArray, phase: NDArray, deg: bool = True, dBm: bool = True ) -> tuple[NDArray, NDArray]: r""" Converts magnitude and phase data into real and imaginary. Parameters ---------- mag : NDArray Magnitude array. phase : NDArray Phase array deg : bool, optional Set to ``True`` if the phase is in degrees. Defaults to ``True``. dBm : bool, optional Set to ``True`` if the magnitude is in dBm. Defaults to ``True``. Notes ----- This conversion is defined as .. math:: S_{21}^\text{complex} = 10^{\frac{|S_{21}|}{20}}e^{i\phi} where the magnitude :math:`|S_{21}|` is in dB and the phase :math:`\phi` is in degrees. """ if deg: phase = np.deg2rad(phase) if dBm: s21_complex = 10 ** (mag / 20) * np.exp(1j * phase) else: s21_complex = mag * np.exp(1j * phase) return s21_complex.real, s21_complex.imag
[docs] def convert_complex_to_magphase( real: NDArray, imag: NDArray, deg: bool = True ) -> tuple[NDArray, NDArray]: r""" Converts real and imaginary data into magnitude (dBm) and phase. Parameters ---------- real : NDArray Real data array. imag : NDArray Imaginary data array. deg : bool, optional If ``True`` the phase is returned in degrees. Defaults to ``True``. Notes ----- This conversion is defined as .. math:: |S_{21}|=20\cdot\log_{10}\sqrt{\mathrm{Re}(S_{21})^2+\mathrm{Im}(S_{21})^2} \phi=\arctan\left(\frac{\mathrm{Im}(S_{21})}{\mathrm{Re}(S_{21})}\right) """ phase = np.angle(real + 1j * imag, deg=deg) mag = 20 * np.log10(np.sqrt(real**2 + imag**2)) return mag, phase
def load_graph_data(path: str) -> dict[str, NDArray]: """ Loads the data saved in csv files by the Grapher objects and returns it as a dictionnary with label as key and NDArrays of the data. Parameters ---------- path : str Complete file file path of the file containing the data. """ df = pd.read_csv(path, header=[0, 1], index_col=0) loaded_data = {} for label in df.columns.get_level_values(0).unique(): loaded_data[label] = np.array(df[label]).T return loaded_data def level_phase(phase: ArrayLike, deg: bool = False) -> ArrayLike: """ Levels the phase by substracting the slope. """ phase = np.asarray(phase) unwrapped_phase = np.unwrap(phase, 180) if deg else np.unwrap(phase) pointA = unwrapped_phase[0] pointB = unwrapped_phase[-1] slope = np.linspace(pointA, pointB, len(unwrapped_phase)) return unwrapped_phase - slope