""" Data conversion functions for Tilt sensors. Converts raw sensor data to physical units (angles, temperatures). """ import numpy as np import logging from typing import Tuple logger = logging.getLogger(__name__) def convert_tilt_link_hr_data( angle_data: np.ndarray, temperature: np.ndarray, calibration_data: np.ndarray, n_sensors: int ) -> Tuple[np.ndarray, np.ndarray]: """ Convert raw Tilt Link HR data to physical units (angles in degrees). Converts MATLAB conv_grezziTLHR.m function. Args: angle_data: Raw angle data (ADC counts) temperature: Raw temperature data calibration_data: Calibration coefficients If column 4 == 0: XY gain is common Column 1: gain XY Column 2: gain temp Column 3: offset temp Else: separate XY gains Column 1: gain X Column 2: gain Y Column 3: gain temp Column 4: offset temp n_sensors: Number of sensors Returns: Tuple of (converted_angles, converted_temperature) """ logger.info(f"Converting Tilt Link HR data for {n_sensors} sensors") n_timestamps = angle_data.shape[0] angle_converted = angle_data.copy() temp_converted = temperature.copy() # Check if XY gains are common or separate if len(calibration_data.shape) == 1 or calibration_data.shape[1] < 4: # Simple case: single calibration set xy_common = True gain_xy = calibration_data[0] if len(calibration_data) > 0 else 1.0 gain_temp = calibration_data[1] if len(calibration_data) > 1 else 1.0 offset_temp = calibration_data[2] if len(calibration_data) > 2 else 0.0 else: # Check column 4 (index 3) if np.all(calibration_data[:, 3] == 0): # XY gains are common xy_common = True gain_angles = calibration_data[:, 0] # Common gain for both axes gain_temp = calibration_data[:, 1] offset_temp = calibration_data[:, 2] else: # Separate XY gains xy_common = False gain_x = calibration_data[:, 0] gain_y = calibration_data[:, 1] gain_temp = calibration_data[:, 2] offset_temp = calibration_data[:, 3] # Convert angles if xy_common: # Common gain for X and Y for i in range(n_sensors): gain = gain_angles[i] if hasattr(gain_angles, '__len__') else gain_xy angle_converted[:, i * 2] = angle_data[:, i * 2] * gain # X angle_converted[:, i * 2 + 1] = angle_data[:, i * 2 + 1] * gain # Y else: # Separate gains for X and Y for i in range(n_sensors): angle_converted[:, i * 2] = angle_data[:, i * 2] * gain_x[i] # X angle_converted[:, i * 2 + 1] = angle_data[:, i * 2 + 1] * gain_y[i] # Y # Convert temperatures for i in range(n_sensors): g_temp = gain_temp[i] if hasattr(gain_temp, '__len__') else gain_temp off_temp = offset_temp[i] if hasattr(offset_temp, '__len__') else offset_temp temp_converted[:, i] = temperature[:, i] * g_temp + off_temp logger.info("Tilt Link HR data conversion completed") return angle_converted, temp_converted def convert_tilt_link_data( acceleration: np.ndarray, temperature: np.ndarray, calibration_data: np.ndarray, n_sensors: int ) -> Tuple[np.ndarray, np.ndarray]: """ Convert raw Tilt Link data to physical units (acceleration in g). Similar to RSN conversion but for standard Tilt Link sensors. Args: acceleration: Raw acceleration data temperature: Raw temperature data calibration_data: Calibration coefficients for each sensor n_sensors: Number of sensors Returns: Tuple of (converted_acceleration, converted_temperature) """ logger.info(f"Converting Tilt Link data for {n_sensors} sensors") n_timestamps = acceleration.shape[0] acc_converted = np.zeros_like(acceleration) temp_converted = np.zeros_like(temperature) for i in range(n_sensors): cal = calibration_data[i] # Acceleration conversion (typically 2 or 3 axes) # Assume biaxial for Tilt Link acc_converted[:, i * 2] = cal[0] * acceleration[:, i * 2] + cal[1] # X acc_converted[:, i * 2 + 1] = cal[2] * acceleration[:, i * 2 + 1] + cal[3] # Y # Temperature conversion if len(cal) > 4: temp_converted[:, i] = cal[4] * temperature[:, i] + cal[5] else: temp_converted[:, i] = temperature[:, i] logger.info("Tilt Link data conversion completed") return acc_converted, temp_converted def convert_biaxial_link_data( raw_data: np.ndarray, temperature: np.ndarray, calibration_data: np.ndarray, n_sensors: int ) -> Tuple[np.ndarray, np.ndarray]: """ Convert raw Biaxial Link (BL) data to physical units. Converts MATLAB conv_grezziBL.m function. Args: raw_data: Raw sensor data temperature: Raw temperature data calibration_data: Calibration coefficients n_sensors: Number of sensors Returns: Tuple of (converted_data, converted_temperature) """ logger.info(f"Converting Biaxial Link data for {n_sensors} sensors") data_converted = np.zeros_like(raw_data) temp_converted = np.zeros_like(temperature) for i in range(n_sensors): cal = calibration_data[i] # Biaxial: 2 axes per sensor data_converted[:, i * 2] = cal[0] * raw_data[:, i * 2] + cal[1] data_converted[:, i * 2 + 1] = cal[2] * raw_data[:, i * 2 + 1] + cal[3] # Temperature if len(cal) > 4: temp_converted[:, i] = cal[4] * temperature[:, i] + cal[5] else: temp_converted[:, i] = temperature[:, i] logger.info("Biaxial Link data conversion completed") return data_converted, temp_converted def convert_pendulum_link_data( raw_data: np.ndarray, temperature: np.ndarray, calibration_data: np.ndarray, n_sensors: int ) -> Tuple[np.ndarray, np.ndarray]: """ Convert raw Pendulum Link (PL) data to physical units. Args: raw_data: Raw sensor data temperature: Raw temperature data calibration_data: Calibration coefficients n_sensors: Number of sensors Returns: Tuple of (converted_data, converted_temperature) """ logger.info(f"Converting Pendulum Link data for {n_sensors} sensors") data_converted = np.zeros_like(raw_data) temp_converted = np.zeros_like(temperature) for i in range(n_sensors): cal = calibration_data[i] # Pendulum typically has 2 axes data_converted[:, i * 2] = cal[0] * raw_data[:, i * 2] + cal[1] data_converted[:, i * 2 + 1] = cal[2] * raw_data[:, i * 2 + 1] + cal[3] # Temperature if len(cal) > 4: temp_converted[:, i] = cal[4] * temperature[:, i] + cal[5] else: temp_converted[:, i] = temperature[:, i] logger.info("Pendulum Link data conversion completed") return data_converted, temp_converted def convert_kessler_link_data( raw_data: np.ndarray, temperature: np.ndarray, calibration_data: np.ndarray, n_sensors: int ) -> Tuple[np.ndarray, np.ndarray]: """ Convert raw Kessler Link (KL/KLHR) data to physical units. Converts MATLAB conv_grezziKLHR.m function. Args: raw_data: Raw sensor data temperature: Raw temperature data calibration_data: Calibration coefficients n_sensors: Number of sensors Returns: Tuple of (converted_data, converted_temperature) """ logger.info(f"Converting Kessler Link data for {n_sensors} sensors") data_converted = np.zeros_like(raw_data) temp_converted = np.zeros_like(temperature) for i in range(n_sensors): cal = calibration_data[i] # Kessler biaxial inclinometer data_converted[:, i * 2] = cal[0] * raw_data[:, i * 2] + cal[1] data_converted[:, i * 2 + 1] = cal[2] * raw_data[:, i * 2 + 1] + cal[3] # Temperature if len(cal) > 4: temp_converted[:, i] = cal[4] * temperature[:, i] + cal[5] else: temp_converted[:, i] = temperature[:, i] logger.info("Kessler Link data conversion completed") return data_converted, temp_converted def convert_thermistor_data( raw_data: np.ndarray, calibration_data: np.ndarray, n_sensors: int ) -> np.ndarray: """ Convert raw thermistor (ThL) data to temperature in Celsius. Converts MATLAB conv_grezziThL.m function. Args: raw_data: Raw ADC values calibration_data: Calibration coefficients (gain, offset) n_sensors: Number of sensors Returns: Converted temperature array """ logger.info(f"Converting Thermistor data for {n_sensors} sensors") temp_converted = np.zeros_like(raw_data) for i in range(n_sensors): cal = calibration_data[i] # Linear conversion: T = gain * ADC + offset temp_converted[:, i] = cal[0] * raw_data[:, i] + cal[1] logger.info("Thermistor data conversion completed") return temp_converted def convert_pt100_data( raw_data: np.ndarray, calibration_data: np.ndarray, n_sensors: int ) -> np.ndarray: """ Convert raw PT100 sensor data to temperature in Celsius. Converts MATLAB conv_grezziPT100.m function. Args: raw_data: Raw resistance or ADC values calibration_data: Calibration coefficients n_sensors: Number of sensors Returns: Converted temperature array """ logger.info(f"Converting PT100 data for {n_sensors} sensors") temp_converted = np.zeros_like(raw_data) for i in range(n_sensors): cal = calibration_data[i] # PT100 typically linear: T = gain * R + offset temp_converted[:, i] = cal[0] * raw_data[:, i] + cal[1] logger.info("PT100 data conversion completed") return temp_converted