| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- #!/usr/bin/env python3
- """Shared metric registry for the per-angle-bin indicator analysis.
- Two families:
- * ``BIN_METRICS`` : computed on the raw samples **inside each angular bin**;
- * ``CYCLE_METRICS`` : computed **once per cycle** (plateau levels, valve-event
- angles, corner slopes) and repeated on every bin row of that cycle.
- ``VOLATILE`` metrics are amplitude/irregularity-like (a change means the local
- waveform got rougher/noisier); the rest are level/shape-like.
- """
- from __future__ import annotations
- BIN_METRICS = (
- # 旧的 6 个
- "mean", "range", "std", "mad", "slope", "roughness",
- # 分布
- "p10", "p50", "p90", "iqr", "skew", "kurt",
- # 导数 / 振荡
- "d_abs_mean", "d_abs_max", "d_rms", "d2_rms", "zero_cross", "n_extrema",
- # 形状 / 复杂度
- "d2_abs_max", "tv", "mean_cross", "mobility", "complexity",
- )
- CYCLE_METRICS = (
- "p_suction", "p_discharge", "pressure_ratio", "suction_frac", "discharge_frac",
- "angle_min", "angle_max", "cross_up", "cross_down",
- "max_rise", "max_fall", "max_rise_angle", "max_fall_angle",
- )
- META_COLUMNS = (
- "unit", "cylinder", "stage", "side", "point_name", "wave_file_id",
- "sample_time", "rpm", "n_samples", "p_min", "p_max", "p_span",
- "bin", "bin_start", "n_raw",
- )
- VOLATILE = (
- "std", "mad", "range", "roughness",
- "d_abs_mean", "d_abs_max", "d_rms", "d2_rms", "zero_cross", "n_extrema",
- "d2_abs_max", "tv", "mean_cross", "mobility", "complexity",
- )
- # 整周期指标里偏“波动/不稳定”的(其余按水平处理)
- CYCLE_VOLATILE = ("suction_frac", "discharge_frac", "max_rise", "max_fall")
- # 角度型指标:差值与中位数必须按 0-360 环形处理(否则 wrap 会产生假跳变)
- ANGLE_METRICS = ("angle_min", "angle_max", "cross_up", "cross_down", "max_rise_angle", "max_fall_angle")
- # 随压力幅度(p_span)成比例的量;--normalize span 时除以本周期 p_span 以消工况
- BIN_SCALED = (
- "mean", "range", "std", "mad", "slope", "roughness",
- "p10", "p50", "p90", "iqr",
- "d_abs_mean", "d_abs_max", "d_rms", "d2_rms", "d2_abs_max", "tv",
- )
- CYCLE_SCALED = ("p_suction", "p_discharge", "max_rise", "max_fall")
- def apply_normalization(rows, mode: str) -> None:
- """In place: divide pressure-scale metrics by each cycle's own ``p_span``."""
- if mode != "span":
- return
- scaled = set(BIN_SCALED) | set(CYCLE_SCALED)
- for row in rows:
- span = row.get("p_span") or 0.0
- for name in scaled:
- if row.get(name) is None:
- continue
- row[name] = row[name] / span if span > 1e-9 else None
- ALL_METRICS = BIN_METRICS + CYCLE_METRICS
- FIELDNAMES = META_COLUMNS + BIN_METRICS + CYCLE_METRICS
|