# %% import numpy as np import pandas as pd def parse_csv_data(file_path, numeric_columns=None, timestamp_column=None): """ Parses data from a CSV file and returns a cleaned DataFrame. Args: file_path (str): Path to the CSV file containing data. numeric_columns (list of str, optional): List of columns to convert to numeric, ignoring errors. timestamp_column (str, optional): Column name to convert to datetime. Returns: pd.DataFrame: A cleaned DataFrame with parsed numeric columns and optional timestamp conversion. """ # Load and clean the CSV file data = pd.read_csv(file_path) data.columns = data.columns.str.replace('"', '').str.strip() # Convert specified columns to numeric if numeric_columns: data[numeric_columns] = data[numeric_columns].apply(pd.to_numeric, errors='coerce') data = data.dropna(subset=numeric_columns) # Drop rows with NaNs in numeric columns # Convert Unix timestamp to datetime if timestamp_column: data['timestamp'] = pd.to_datetime(data[timestamp_column], unit='s') return data def compute_central_difference(time, temperature): """ Computes the central difference derivative for temperature with respect to time. Args: time (array-like): Array of time points. temperature (array-like): Array of temperature values. Returns: tuple: Aligned time points, aligned temperatures, and computed derivative. """ time = np.asarray(time) temperature = np.asarray(temperature) # Central difference calculation for dT/dt dT_dt = (temperature[2:] - temperature[:-2]) / (time[2:] - time[:-2]) time_aligned = time[1:-1] temperature_aligned = temperature[1:-1] return time_aligned, temperature_aligned, dT_dt def fit_log_linear_model(time, temperature, derivative): """ Fits a log-linear model to determine parameters k and n for a power-law relationship. Args: time (array-like): Array of aligned time points. temperature (array-like): Array of aligned temperature values. derivative (array-like): Array of temperature derivatives. Returns: tuple: Parameters k and n of the fitted model. """ log_temperature = np.log(temperature) log_derivative = np.log(np.abs(derivative)) # Linear regression to find slope (n) and intercept (log(k)) # Calculate the means of log_T and log_dT_dt mean_log_temperature = np.mean(log_temperature) mean_log_derivative = np.mean(log_derivative) # Calculate the terms needed for the slope (n) and intercept (log(k)) SS_xy = np.sum((log_temperature - mean_log_temperature) * (log_derivative - mean_log_derivative)) SS_xx = np.sum((log_temperature - mean_log_temperature) ** 2) # Calculate slope and intercept slope = SS_xy / SS_xx intercept = mean_log_derivative - slope * mean_log_temperature # Calculate parameters k and n from the linear fit n = slope k = np.exp(intercept) return k, n k = np.exp(intercept) n = slope return k, n def smooth_data(time, temperature, window_width, sigma): """ Smooths temperature data using a Gaussian kernel. Args: time (array-like): Array of time points. temperature (array-like): Array of temperature values. window_width (float): Width of the Gaussian window in time units. sigma (float): Standard deviation of the Gaussian kernel in time units. Returns: tuple: Trimmed time and smoothed temperature. """ time = np.asarray(time) temperature = np.asarray(temperature) dt = np.mean(np.diff(time)) window_points = int(window_width / dt) sigma_points = sigma / dt # Generate Gaussian kernel half_window = window_points // 2 x = np.arange(-half_window, half_window + 1) gaussian_kernel = np.exp(-0.5 * (x / sigma_points) ** 2) gaussian_kernel /= gaussian_kernel.sum() # Perform convolution manually smoothed_temperature = np.zeros_like(temperature) for i in range(len(temperature)): weighted_sum = 0 kernel_sum = 0 for j, kernel_value in enumerate(gaussian_kernel): idx = i + j - half_window if 0 <= idx < len(temperature): weighted_sum += temperature[idx] * kernel_value kernel_sum += kernel_value smoothed_temperature[i] = weighted_sum / kernel_sum if kernel_sum != 0 else 0 # Trim the boundary to avoid edge effects trim_points = half_window trimmed_time = time[trim_points:-trim_points] trimmed_temperature = smoothed_temperature[trim_points:-trim_points] return trimmed_time, trimmed_temperature # Load and process data file_path = 'graph(3).csv' df = parse_csv_data(file_path, numeric_columns=['flow_pt1000', 'temperature_inside'], timestamp_column='Unix timestamp') # Prepare data for analysis time = np.array(df['Unix timestamp']) time -= time[0] # Normalize time to start at zero temperature_difference = np.array(df['flow_pt1000'] - df['temperature_inside']) # Filter data for significant temperature differences min_temp_difference = 2 valid_indices = temperature_difference > min_temp_difference time_valid = time[valid_indices] temp_difference_valid = temperature_difference[valid_indices] # Smooth the data time_smooth, temp_smooth = smooth_data(time_valid, temp_difference_valid, window_width=60, sigma=300) # Compute central difference derivative time_aligned, temp_aligned, derivative = compute_central_difference(time_smooth, temp_smooth) # Fit parameters using log-linear model k, n = fit_log_linear_model(time_aligned, temp_aligned, derivative) print(f"Fitted parameters: k = {k}, n = {n}")