Skip to content

Commit 7a88739

Browse files
committed
docs(skill): create and synchronize pivpy/skill.md and skills/pivpy/SKILL.md for OpenPIV interoperability, publication figures, and deep reporting
1 parent cc29721 commit 7a88739

2 files changed

Lines changed: 376 additions & 0 deletions

File tree

pivpy/skill.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
---
2+
name: pivpy
3+
description: >-
4+
Expert skill for deep Particle Image Velocimetry (PIV) vector field analysis, post-processing,
5+
vortex topology identification, spatial filtering, outlier cleaning, and publication-ready figures/reports.
6+
Designed to work in tandem with openpiv-skill and scientific reporting workflows.
7+
---
8+
9+
# PIVPy Skill: Deep PIV Analysis, Visualization & Reporting
10+
11+
This skill equips the agent with comprehensive domain expertise, workflows, and code recipes for processing, analyzing, and visualizing Particle Image Velocimetry (PIV) data using **PIVPy** (built on top of `xarray`, `numpy`, `scipy`, and `matplotlib`).
12+
13+
---
14+
15+
## 1. System Architecture & Interoperability
16+
17+
```
18+
+---------------------+ +----------------------+ +-----------------------+
19+
| Raw Image Pairs | ----> | openpiv-skill | ----> | Raw Velocity Fields |
20+
| (TIF, BMP, PNG) | | (cross-correlation) | | (TXT, DAT, VC7, NC) |
21+
+---------------------+ +----------------------+ +-----------+-----------+
22+
|
23+
v
24+
+------------------------------------------------------------------------------------+
25+
| PIVPy Skill |
26+
| |
27+
| 1. Canonical Ingestion: build_dataset(), load_directory(), from_openpiv() |
28+
| 2. Validation & Clean: normalized_median_test(), clean(), harmonic inpainting |
29+
| 3. Spatial Filtering: smooth(method='gaussian' | 'median' | 'butterworth') |
30+
| 4. Kinematic & Topology: vorticity, Gamma1, Gamma2, Q-criterion, Okubo-Weiss |
31+
| 5. Gradient & Strain: gradient_tensor(), max_shear(), acceleration() |
32+
| 6. Turbulence & Spectra: Reynolds decomposition, E(k), dissipation, R_ij(r) |
33+
| 7. Publication Figures: piv.plot(), marimo notebooks, animations, LaTeX reports|
34+
+------------------------------------------------------------------------------------+
35+
```
36+
37+
---
38+
39+
## 2. Canonical Data Model (`xarray.Dataset`)
40+
41+
Every PIV field in PIVPy is represented as an `xarray.Dataset` containing:
42+
- **Dimensions**: `('y', 'x')` for single frames, `('y', 'x', 't')` for time series / ensembles.
43+
- **Coordinates**:
44+
- `x`: 1D array of horizontal positions $[x_0, x_1, \dots, x_{N-1}]$.
45+
- `y`: 1D array of vertical positions $[y_0, y_1, \dots, y_{M-1}]$.
46+
- `t`: 1D array of time stamps or frame indices $[t_0, t_1, \dots, t_{K-1}]$ (optional).
47+
- **Required Data Variables**:
48+
- `u`: Horizontal velocity component $[M \times N]$ or $[M \times N \times K]$.
49+
- `v`: Vertical velocity component $[M \times N]$ or $[M \times N \times K]$.
50+
- `chc`: Vector validation flag channel ($1.0 = \text{valid}$, $0.0 = \text{spurious/outlier}$).
51+
- **Attributes (`attrs`)**: `units_x`, `units_y`, `units_u`, `units_v`, `units_t`, `dt`, `history`.
52+
53+
---
54+
55+
## 3. Standard PIV Processing Pipeline
56+
57+
### Step 1: Ingestion from OpenPIV or Files
58+
59+
```python
60+
import xarray as xr
61+
import pivpy.pivpy # Registers .piv accessor
62+
from pivpy import io
63+
64+
# Option A: From OpenPIV output files / directories
65+
ds = io.load_directory("path/to/openpiv_results/", extension=".txt")
66+
67+
# Option B: From OpenPIV arrays directly in memory
68+
from pivpy.schema import build_dataset
69+
ds = build_dataset(x=x, y=y, u=u, v=v, chc=flags, dt=0.001)
70+
71+
# Option C: Out-of-core streaming from Zarr archive
72+
ds = io.open_zarr("dataset.zarr")
73+
```
74+
75+
### Step 2: Outlier Rejection & Inpainting (Normalized Median Test)
76+
77+
```python
78+
# Westerweel & Scarano (2005) Normalized Median Test + Harmonic Inpainting
79+
ds_clean = ds.piv.clean(
80+
method="normalized_median",
81+
threshold=2.0, # Residual threshold (typically 2.0)
82+
epsilon=0.1, # Velocity noise floor
83+
inpaint_method=0, # 0 = harmonic Laplacian, 1 = nearest, 2 = linear
84+
radius=1, # 3x3 stencil (radius=1) or 5x5 stencil (radius=2)
85+
)
86+
```
87+
88+
### Step 3: Spatial Filtering & Denoising
89+
90+
```python
91+
# Gaussian smoothing
92+
ds_smooth = ds_clean.piv.smooth(sigma=1.2, method="gaussian")
93+
94+
# Frequency-domain Butterworth filter
95+
ds_bw = ds_clean.piv.smooth(sigma=8.0, method="butterworth", order=2.0)
96+
```
97+
98+
### Step 4: Vortex Identification & Kinematic Diagnostics
99+
100+
```python
101+
# 1. Circulation-based noise-robust vorticity (77% error reduction vs standard diff)
102+
ds_vort = ds_smooth.piv.vorticity(name="vorticity", method="circulation", radius=2)
103+
104+
# 2. Topology Identification: Gamma1 (vortex center) and Gamma2 (boundary)
105+
ds_g1 = ds_smooth.piv.gamma1(name="gamma1", radius=3)
106+
ds_g2 = ds_smooth.piv.gamma2(name="gamma2", radius=3)
107+
108+
# 3. Galilean-invariant Q-criterion & Okubo-Weiss parameter
109+
ds_q = ds_smooth.piv.q_criterion(name="Q")
110+
ds_ow = ds_smooth.piv.okubo_weiss(name="OW")
111+
112+
# 4. Solid-body rotation subtraction
113+
ds_nobr = ds_smooth.piv.subsbr()
114+
```
115+
116+
### Step 5: Velocity Gradient & Acceleration Analysis
117+
118+
```python
119+
# Full strain rate tensor decomposition
120+
tensor = ds_smooth.piv.gradient_tensor(return_components=True)
121+
# Contains: s_xx, s_yy, s_xy, lambda_1, lambda_2, max_shear, strain_angle
122+
123+
# Total Material Acceleration D(u)/Dt (unsteady + convective)
124+
ds_accel = ds_smooth.piv.acceleration(name="accel", unsteady=True)
125+
```
126+
127+
---
128+
129+
## 4. Publication-Ready Visualizations
130+
131+
### Beautiful Single-Frame Quiver & Contour Plots
132+
133+
```python
134+
import matplotlib.pyplot as plt
135+
136+
# Generate high-contrast, publication-quality figure
137+
fig, ax = plt.subplots(figsize=(7, 5), dpi=300)
138+
139+
ds.piv.plot(
140+
flow_property="vorticity", # Background scalar
141+
cmap="RdBu_r", # Diverging colormap
142+
clim=(-15, 15), # Symmetric color limits
143+
cbar=True,
144+
cbar_label=r"Vorticity $\omega_z$ [s$^{-1}$]",
145+
quiver_scale=1.0, # Optimized arrow scaling
146+
quiver_density=2, # Subsample grid for clear arrow visibility
147+
quiver_color="k",
148+
quiver_width=0.003,
149+
quiver_alpha=0.75,
150+
ax=ax,
151+
)
152+
153+
ax.set_xlabel(r"$x$ [mm]", fontsize=12)
154+
ax.set_ylabel(r"$y$ [mm]", fontsize=12)
155+
ax.set_title("Vortical Wake Evolution", fontsize=14, pad=10)
156+
fig.tight_layout()
157+
fig.savefig("figure_vortex_wake.pdf", bbox_inches="tight")
158+
```
159+
160+
### Fluid Dynamics Quiver Animation (MP4 / GIF)
161+
162+
```python
163+
anim = ds.piv.animate(
164+
flow_property="vorticity",
165+
cmap="Spectral_r",
166+
quiver_scale=0.8,
167+
quiver_density=3,
168+
quiver_color="midnightblue",
169+
quiver_width=0.0035,
170+
quiver_alpha=0.7,
171+
fps=15,
172+
blur=0.6,
173+
save_path="vortex_pair_dynamics.gif",
174+
)
175+
```
176+
177+
---
178+
179+
## 5. Automated Deep PIV Analysis Reports
180+
181+
When generating comprehensive analysis reports for experiments:
182+
1. **Quality Audit Table**: Report total vectors, percentage of valid vs inpainted vectors, mean velocity magnitude, peak Reynolds stresses, and vortex core circulation $\Gamma$.
183+
2. **Multi-Panel Overview**:
184+
- Panel A: Streamwise & transverse velocity contours ($u, v$).
185+
- Panel B: Circulation vorticity & $\Gamma_2$ vortex boundary contours.
186+
- Panel C: $Q$-criterion & Okubo-Weiss topology partitioning.
187+
- Panel D: Maximum shear strain rate & material acceleration.
188+
3. **Artifact Generation**: Save high-resolution PNG/PDF figures and export analysis summary markdown artifacts.

skills/pivpy/SKILL.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
---
2+
name: pivpy
3+
description: >-
4+
Expert skill for deep Particle Image Velocimetry (PIV) vector field analysis, post-processing,
5+
vortex topology identification, spatial filtering, outlier cleaning, and publication-ready figures/reports.
6+
Designed to work in tandem with openpiv-skill and scientific reporting workflows.
7+
---
8+
9+
# PIVPy Skill: Deep PIV Analysis, Visualization & Reporting
10+
11+
This skill equips the agent with comprehensive domain expertise, workflows, and code recipes for processing, analyzing, and visualizing Particle Image Velocimetry (PIV) data using **PIVPy** (built on top of `xarray`, `numpy`, `scipy`, and `matplotlib`).
12+
13+
---
14+
15+
## 1. System Architecture & Interoperability
16+
17+
```
18+
+---------------------+ +----------------------+ +-----------------------+
19+
| Raw Image Pairs | ----> | openpiv-skill | ----> | Raw Velocity Fields |
20+
| (TIF, BMP, PNG) | | (cross-correlation) | | (TXT, DAT, VC7, NC) |
21+
+---------------------+ +----------------------+ +-----------+-----------+
22+
|
23+
v
24+
+------------------------------------------------------------------------------------+
25+
| PIVPy Skill |
26+
| |
27+
| 1. Canonical Ingestion: build_dataset(), load_directory(), from_openpiv() |
28+
| 2. Validation & Clean: normalized_median_test(), clean(), harmonic inpainting |
29+
| 3. Spatial Filtering: smooth(method='gaussian' | 'median' | 'butterworth') |
30+
| 4. Kinematic & Topology: vorticity, Gamma1, Gamma2, Q-criterion, Okubo-Weiss |
31+
| 5. Gradient & Strain: gradient_tensor(), max_shear(), acceleration() |
32+
| 6. Turbulence & Spectra: Reynolds decomposition, E(k), dissipation, R_ij(r) |
33+
| 7. Publication Figures: piv.plot(), marimo notebooks, animations, LaTeX reports|
34+
+------------------------------------------------------------------------------------+
35+
```
36+
37+
---
38+
39+
## 2. Canonical Data Model (`xarray.Dataset`)
40+
41+
Every PIV field in PIVPy is represented as an `xarray.Dataset` containing:
42+
- **Dimensions**: `('y', 'x')` for single frames, `('y', 'x', 't')` for time series / ensembles.
43+
- **Coordinates**:
44+
- `x`: 1D array of horizontal positions $[x_0, x_1, \dots, x_{N-1}]$.
45+
- `y`: 1D array of vertical positions $[y_0, y_1, \dots, y_{M-1}]$.
46+
- `t`: 1D array of time stamps or frame indices $[t_0, t_1, \dots, t_{K-1}]$ (optional).
47+
- **Required Data Variables**:
48+
- `u`: Horizontal velocity component $[M \times N]$ or $[M \times N \times K]$.
49+
- `v`: Vertical velocity component $[M \times N]$ or $[M \times N \times K]$.
50+
- `chc`: Vector validation flag channel ($1.0 = \text{valid}$, $0.0 = \text{spurious/outlier}$).
51+
- **Attributes (`attrs`)**: `units_x`, `units_y`, `units_u`, `units_v`, `units_t`, `dt`, `history`.
52+
53+
---
54+
55+
## 3. Standard PIV Processing Pipeline
56+
57+
### Step 1: Ingestion from OpenPIV or Files
58+
59+
```python
60+
import xarray as xr
61+
import pivpy.pivpy # Registers .piv accessor
62+
from pivpy import io
63+
64+
# Option A: From OpenPIV output files / directories
65+
ds = io.load_directory("path/to/openpiv_results/", extension=".txt")
66+
67+
# Option B: From OpenPIV arrays directly in memory
68+
from pivpy.schema import build_dataset
69+
ds = build_dataset(x=x, y=y, u=u, v=v, chc=flags, dt=0.001)
70+
71+
# Option C: Out-of-core streaming from Zarr archive
72+
ds = io.open_zarr("dataset.zarr")
73+
```
74+
75+
### Step 2: Outlier Rejection & Inpainting (Normalized Median Test)
76+
77+
```python
78+
# Westerweel & Scarano (2005) Normalized Median Test + Harmonic Inpainting
79+
ds_clean = ds.piv.clean(
80+
method="normalized_median",
81+
threshold=2.0, # Residual threshold (typically 2.0)
82+
epsilon=0.1, # Velocity noise floor
83+
inpaint_method=0, # 0 = harmonic Laplacian, 1 = nearest, 2 = linear
84+
radius=1, # 3x3 stencil (radius=1) or 5x5 stencil (radius=2)
85+
)
86+
```
87+
88+
### Step 3: Spatial Filtering & Denoising
89+
90+
```python
91+
# Gaussian smoothing
92+
ds_smooth = ds_clean.piv.smooth(sigma=1.2, method="gaussian")
93+
94+
# Frequency-domain Butterworth filter
95+
ds_bw = ds_clean.piv.smooth(sigma=8.0, method="butterworth", order=2.0)
96+
```
97+
98+
### Step 4: Vortex Identification & Kinematic Diagnostics
99+
100+
```python
101+
# 1. Circulation-based noise-robust vorticity (77% error reduction vs standard diff)
102+
ds_vort = ds_smooth.piv.vorticity(name="vorticity", method="circulation", radius=2)
103+
104+
# 2. Topology Identification: Gamma1 (vortex center) and Gamma2 (boundary)
105+
ds_g1 = ds_smooth.piv.gamma1(name="gamma1", radius=3)
106+
ds_g2 = ds_smooth.piv.gamma2(name="gamma2", radius=3)
107+
108+
# 3. Galilean-invariant Q-criterion & Okubo-Weiss parameter
109+
ds_q = ds_smooth.piv.q_criterion(name="Q")
110+
ds_ow = ds_smooth.piv.okubo_weiss(name="OW")
111+
112+
# 4. Solid-body rotation subtraction
113+
ds_nobr = ds_smooth.piv.subsbr()
114+
```
115+
116+
### Step 5: Velocity Gradient & Acceleration Analysis
117+
118+
```python
119+
# Full strain rate tensor decomposition
120+
tensor = ds_smooth.piv.gradient_tensor(return_components=True)
121+
# Contains: s_xx, s_yy, s_xy, lambda_1, lambda_2, max_shear, strain_angle
122+
123+
# Total Material Acceleration D(u)/Dt (unsteady + convective)
124+
ds_accel = ds_smooth.piv.acceleration(name="accel", unsteady=True)
125+
```
126+
127+
---
128+
129+
## 4. Publication-Ready Visualizations
130+
131+
### Beautiful Single-Frame Quiver & Contour Plots
132+
133+
```python
134+
import matplotlib.pyplot as plt
135+
136+
# Generate high-contrast, publication-quality figure
137+
fig, ax = plt.subplots(figsize=(7, 5), dpi=300)
138+
139+
ds.piv.plot(
140+
flow_property="vorticity", # Background scalar
141+
cmap="RdBu_r", # Diverging colormap
142+
clim=(-15, 15), # Symmetric color limits
143+
cbar=True,
144+
cbar_label=r"Vorticity $\omega_z$ [s$^{-1}$]",
145+
quiver_scale=1.0, # Optimized arrow scaling
146+
quiver_density=2, # Subsample grid for clear arrow visibility
147+
quiver_color="k",
148+
quiver_width=0.003,
149+
quiver_alpha=0.75,
150+
ax=ax,
151+
)
152+
153+
ax.set_xlabel(r"$x$ [mm]", fontsize=12)
154+
ax.set_ylabel(r"$y$ [mm]", fontsize=12)
155+
ax.set_title("Vortical Wake Evolution", fontsize=14, pad=10)
156+
fig.tight_layout()
157+
fig.savefig("figure_vortex_wake.pdf", bbox_inches="tight")
158+
```
159+
160+
### Fluid Dynamics Quiver Animation (MP4 / GIF)
161+
162+
```python
163+
anim = ds.piv.animate(
164+
flow_property="vorticity",
165+
cmap="Spectral_r",
166+
quiver_scale=0.8,
167+
quiver_density=3,
168+
quiver_color="midnightblue",
169+
quiver_width=0.0035,
170+
quiver_alpha=0.7,
171+
fps=15,
172+
blur=0.6,
173+
save_path="vortex_pair_dynamics.gif",
174+
)
175+
```
176+
177+
---
178+
179+
## 5. Automated Deep PIV Analysis Reports
180+
181+
When generating comprehensive analysis reports for experiments:
182+
1. **Quality Audit Table**: Report total vectors, percentage of valid vs inpainted vectors, mean velocity magnitude, peak Reynolds stresses, and vortex core circulation $\Gamma$.
183+
2. **Multi-Panel Overview**:
184+
- Panel A: Streamwise & transverse velocity contours ($u, v$).
185+
- Panel B: Circulation vorticity & $\Gamma_2$ vortex boundary contours.
186+
- Panel C: $Q$-criterion & Okubo-Weiss topology partitioning.
187+
- Panel D: Maximum shear strain rate & material acceleration.
188+
3. **Artifact Generation**: Save high-resolution PNG/PDF figures and export analysis summary markdown artifacts.

0 commit comments

Comments
 (0)