Source code for TKEanalyst.flowstat

import numpy as np
import logging


[docs]def flowstat(time, u, v, w1, w2, profile_type="lp"): """Calculate ADV data statistics Args: time (np.array): time in seconds u (np.array): streamweise velocity along x-axis (positive in bulk flow direction) v (np.array): perpendicular velocity along y-axis w1 (np.array): vertical velocity if side is DOWN w2 (np.array): vertical velocity if side is not DOWN profile_type (str): orientation of the probe (default: lp, which mean probe looks like FlowTracker in a river) Returns: time_series (dict): keys correspond to series names and values to full time series stats (dict(dict)): keys correspond to series names with STAT for autoreplacement with STAT type of nested dictionaries with AVRG, STD and STDERR """ if profile_type == "lp": w = w1 else: w = w2 # flow statistics: velocity (m/s), mean (m/s), rms (m/s), stderr (m/s) u_stats = { "average": np.nanmean(u), "std": np.nanstd(u), "stderr": np.nanstd(u) / np.sqrt(np.count_nonzero(~np.isnan(u))) } v_stats = { "average": np.nanmean(v), "std": np.nanstd(v), "stderr": np.nanstd(v) / np.sqrt(np.count_nonzero(~np.isnan(v))) } w_stats = { "average": np.nanmean(w), "std": np.nanstd(w), "stderr": np.nanstd(w) / np.sqrt(np.count_nonzero(~np.isnan(w))) } # calculate Reynolds stress for u and v tau_re0 = np.multiply(u - u_stats["average"], v - v_stats["average"]) tau_re0_stats = { "average": np.nanmean(tau_re0), "std": np.nanstd(tau_re0), "stderr": np.nanstd(tau_re0) / np.sqrt(np.count_nonzero(~np.isnan(tau_re0))) } # calculate Reynolds stress for u and w1 tau_re1 = np.multiply(u - u_stats["average"], w - w_stats["average"]) tau_re1_stats = { "average": np.nanmean(tau_re1), "std": np.nanstd(tau_re1), "stderr": np.nanstd(tau_re1) / np.sqrt(np.count_nonzero(~np.isnan(tau_re1))) } # calculate TKE k_t1 in m^2/s^2 k_t1 = 0.5 * (u_stats["std"] ** 2 + v_stats["std"] ** 2 + w_stats["std"] ** 2) # prepare output data time_series = {"t (s)": time, "u (m/s)": u, "v (m/s)": v, "w1 (m/s)": w1, "tau_v (m^2/s^2)": tau_re0, "tau_w (m^2/s^2)": tau_re1} stats = {"u STAT (m/s)": u_stats, "v STAT (m/s)": v_stats, "w STAT (m/s)": w_stats, "TKE (m^2/s^2)": k_t1, "tau_v STAT (m^2/s^2)": tau_re0_stats, "tau_w STAT (m^2/s^2)": tau_re1_stats} # if downward looking: calculate stats, TKE, and Reynolds stress for u and w2 if not (profile_type == "lp"): w2_stats = { "average": np.nanmean(w2), "std": np.nanstd(w2), "stderr": np.nanstd(w2) / np.sqrt(np.count_nonzero(~np.isnan(w2))) } # calculate TKE k_t1 in m^2/s^2 k_t2 = 0.5 * (u_stats["std"] ** 2 + v_stats["std"] ** 2 + w2_stats["std"] ** 2) tau_re2 = np.multiply(u - u_stats["average"], w2 - w2_stats["average"]) tau_re2_stats = { "average": np.nanmean(tau_re2), "std": np.nanstd(tau_re2), "stderr": np.nanstd(tau_re2) / np.sqrt(np.count_nonzero(~np.isnan(tau_re2))) } else: # build empty data structures for longitudinal profiling w2_stats = { "average": np.nan, "std": np.nan, "stderr": np.nan, } tau_re2 = {"nan": np.nan} k_t2 = {"nan": np.nan} tau_re2_stats = {"nan": np.nan} # update output data time_series.update({"tau_w2 (m^2/s^2)": tau_re2}) stats.update({"TKE2 (m^2/s^2)": k_t2, "tau_w2 STAT (m^2/s^2)": tau_re2_stats, "w2 STAT (m/s)": w2_stats}) return time_series, stats