DynamisLab/src/OID_analysis
Frank14f 6614f18248 OID Analysis: correction-field structure diagnosis pipeline
Complete implementation of Observable-Inferred Decomposition (OID)
for the fluidic pinball project. Covers Phases 0-7 for all 5 scenes
(steady cloak, Karman cloak, illusion 0.75L/1.0L/1.5L).

Key deliverables:
- Full analysis pipeline: configs, utils, 11 collection scripts, 7 phase
  scripts, robustness analysis, figure generator, batch runner
- Data collected: 500 snapshots per scene, separate illusion-position q_blk
- 7 publication-quality figures: force-sig overlap, rank sensitivity,
  OID vs POD comparison, tau_c sensitivity, POD energy, steady metrics,
  white-box chain
- Comprehensive report at docs/OID_analysis_results.md (292 lines)
- Handover document at docs/OID_handover.md
- Updated knowledge base and notes with all Phase 2 results

Core finding: force-relevant and signature-relevant correction structures
systematically separate across control tasks (steady: +0.763 -> Karman: -0.034
-> illusion: -0.082 to -0.932), with OID consistently outperforming POD.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-22 17:18:19 +08:00
..
analysis OID Analysis: correction-field structure diagnosis pipeline 2026-06-22 17:18:19 +08:00
data OID Analysis: correction-field structure diagnosis pipeline 2026-06-22 17:18:19 +08:00
scripts OID Analysis: correction-field structure diagnosis pipeline 2026-06-22 17:18:19 +08:00
utils OID Analysis: correction-field structure diagnosis pipeline 2026-06-22 17:18:19 +08:00
configs.py OID Analysis: correction-field structure diagnosis pipeline 2026-06-22 17:18:19 +08:00
Final_Conclusions.md OID Analysis: correction-field structure diagnosis pipeline 2026-06-22 17:18:19 +08:00
OID_knowledge.md OID Analysis: correction-field structure diagnosis pipeline 2026-06-22 17:18:19 +08:00
OID_notes.md OID Analysis: correction-field structure diagnosis pipeline 2026-06-22 17:18:19 +08:00
README.md OID Analysis: correction-field structure diagnosis pipeline 2026-06-22 17:18:19 +08:00
Sch12.md OID Analysis: correction-field structure diagnosis pipeline 2026-06-22 17:18:19 +08:00

OID_analysis: Observable-Inferred Decomposition for Fluidic Pinball Control

What this directory does

This directory implements an OID (Observable-Inferred Decomposition) pipeline for analyzing which flow structures the DRL controller actually modulates in the fluidic pinball experiments. OID ranks modes by cross-correlation with a chosen observable (force, sensor error), rather than by fluctuation energy (POD).

The three companion documents:

  • OID_knowledge.md -- confirmed facts, hard rules, critical caveats, current results
  • OID_notes.md -- execution plan, task tracking, handover notes
  • This file (README.md) -- engineering entry point, how to run

Critical reading order for new agent:

  1. docs/OID_analysis_results.md -- full project report (start here)
  2. README.md (this file) -- understand scope and how to run
  3. OID_knowledge.md -- know the rules, the results, and pitfalls
  4. OID_notes.md -- understand what's left to do

Current scope (as of 2026-06-22)

All 5 scenes analyzed end-to-end:

Scene Type Source Status
steady_cloak Open-loop constant rotation (rear=+-5.1U0) Collected Full Phases 1-7
karman_re100 PPO (d1a3o12_re100) Replayed from CCD Full Phases 1-7
illusion_0.75L PPO (d1a3o14_075L_2U_400S) Replayed from CCD Full Phases 1-7
illusion_1.0L PPO (d1a3o14_1L_2U_600S) Replayed from CCD Full Phases 1-7
illusion_1.5L PPO (d1a3o14_15L_2U) Replayed from CCD Full Phases 1-7

Fixed scope notes (inherited from SR/CCD):

  • All illusion models use u0=0.01, nu=0.004 (standard defaults from config_flowfield.json)
  • "2U" in model name means S_DIM=14 (2 extra target force observations), NOT 2x velocity
  • SAMPLE_INTERVAL depends on target diameter: 0.75L=400, 1.0L=600, 1.5L=800
  • Illusion q_blk was collected separately from cloak-position q_blk (different geometry)

Directory structure

src/OID_analysis/
  configs.py              # Unified scene metadata (12 scene definitions)
  utils/
    cfd_interface.py      # Re-exports CCD's proven CFD interface
    analysis.py           # CPU-only: POD, OID, PCD, zone statistics, comparison
  scripts/
    collect_*.py          # Data collection scripts (GPU, pycuda_3_10)
    replay_*.py           # Field replay + verification
    compute_delta_fields.py # Phase 0 draft
  analysis/
    phase*.py             # Analysis scripts Phases 1-7 (CPU, sr_env)
    robustness_analysis.py # Rank/tau_c/window/zone robustness
    steady_reanalysis.py  # Steady cloak suppression metrics
    compile_master_table.py # Cross-scene comparison
    make_figures.py       # Generate 7 figures
    run_full_analysis.py  # Batch pipeline runner
  data/
    configs/legacy/       # Legacy CFD configs (symlinked)
    steady_cloak/         # Baseline + controlled fields
    karman_cloak/         # Baseline + controlled fields
    illusion/             # PPO controlled fields
    target_cylinder/      # Reference targets
    derived/              # All analysis results + figures
  OID_knowledge.md        # Knowledge base
  OID_notes.md            # Task tracking
  Final_Conclusions.md    # Six-question conclusions
  Sch12.md                # OID reference paper

docs/
  OID_analysis_results.md # Full project report (7 figures, 292 lines)

How to run

All commands from repo root (/home/frank14f/DynamisLab).

Data collection (GPU, pycuda_3_10)

# Steady group:
conda run -n pycuda_3_10 python src/OID_analysis/scripts/collect_empty_channel.py --device 3 --steps 200
conda run -n pycuda_3_10 python src/OID_analysis/scripts/collect_pinball_baseline.py --device 3 --steps 500
conda run -n pycuda_3_10 python src/OID_analysis/scripts/collect_steady_cloak.py --device 3 --steps 500 --omega-rear 5.1

# Karman group:
conda run -n pycuda_3_10 python src/OID_analysis/scripts/collect_disturbance_only.py --device 1 --steps 500
conda run -n pycuda_3_10 python src/OID_analysis/scripts/collect_karman_blk.py --device 1 --steps 500

# Illusion q_blk (important: separate geometry from cloak):
conda run -n pycuda_3_10 python src/OID_analysis/scripts/collect_illusion_qblk.py --device 3 --steps 500

# PPO field replay (from CCD checkpoints):
conda run -n pycuda_3_10 python src/OID_analysis/scripts/replay_full_fields.py --scene karman_re100 --device 1
conda run -n pycuda_3_10 python src/OID_analysis/scripts/replay_full_fields.py --scene illusion_1.0L --device 3

# Target cylinders:
conda run -n pycuda_3_10 python src/OID_analysis/scripts/collect_target_cylinder.py --diameter 1.0 --device 3 --steps 500

Analysis (CPU only, sr_env)

# Full pipeline for one scene:
cd /home/frank14f/DynamisLab
PYTHONPATH="src:$PYTHONPATH" conda run -n sr_env python3 src/OID_analysis/analysis/run_full_analysis.py --scene karman_re100

# Robustness analysis:
PYTHONPATH="src:$PYTHONPATH" conda run -n sr_env python3 src/OID_analysis/analysis/robustness_analysis.py

# Generate figures:
PYTHONPATH="src:$PYTHONPATH" conda run -n pycuda_3_10 python3 src/OID_analysis/analysis/make_figures.py

# Cross-scene table:
PYTHONPATH="src:$PYTHONPATH" conda run -n sr_env python3 src/OID_analysis/analysis/compile_master_table.py

Replay verification

conda run -n pycuda_3_10 python src/OID_analysis/scripts/replay_verify.py --scene karman_re100 --device 1

Key results

Finding Evidence Confidence
Force-sig structures systematically separate across tasks Monotonic trend: +0.763 -> -0.034 -> -0.082 -> -0.495 -> -0.932 High (rank-stable for 4/5 scenes)
OID beats POD for force prediction OID R2=0.435-0.750 vs POD R2=-2.4 to 0.418 High
OID beats POD for signature prediction OID R2=0.315-0.661 vs POD R2=-0.16 to 0.06 High
OID coordinates != control state force-OID->act R2=0.225 vs obs->act R2=0.956 Confirmed (expected design)
Steady cloak suppresses 99.4% of RMS fluctuation Full-field RMS reduction High

Common pitfalls (read these before making changes)

  1. Always use model name as single source of truth. "2U" = S_DIM=14, NOT 2x velocity. u0 is ALWAYS 0.01.
  2. NEVER use nu_from_re() for illusion models. Only valid for standard S_DIM=12 cases.
  3. Distinguish action_bias from preset_action. They are DIFFERENT. action_bias is for DRL scaling; preset_action is for FIFO warmup.
  4. context.push()/pop() around every run() call. Mandatory for multi-step loops.
  5. Fresh GPU per PPO scene. GPU state contamination degrades similarity. Minimum 4NX/U0 steps separation between scenes on the same GPU.
  6. No field cropping. All fields must be full 1280x512 resolution.
  7. Three-field decomposition is MANDATORY. OID operates on Delta-q_ctl = q_ctl - q_blk, NOT on raw q_ctl.
  8. OID identifies directions within the chosen POD subspace. It CANNOT recover structures truncated by POD rank reduction.

Delivered files (non-data)

These files should be committed to the repository:

Code (src/OID_analysis/):

  • configs.py, utils/cfd_interface.py, utils/analysis.py
  • scripts/ (11 collection + 3 replay scripts)
  • analysis/ (7 phase scripts + robustness + figures + batch runner)
  • OID_knowledge.md, OID_notes.md, Final_Conclusions.md

Report (docs/):

  • docs/OID_analysis_results.md

Large data files (NOT committed -- see .gitignore):

  • All .npz in data/
  • All .npy in data/derived/
  • All .png in data/derived/figures/