bins_common.py 2.7 KB

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