Add unified native-grid visualization tool (mpas_viz) for MPAS post-processing#14
Open
daniloceano wants to merge 10 commits into
Open
Add unified native-grid visualization tool (mpas_viz) for MPAS post-processing#14daniloceano wants to merge 10 commits into
daniloceano wants to merge 10 commits into
Conversation
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- setup_environment.sh: stop inferring env existence from 'conda activate's exit code (which gives a misleading "Couldn't find the environment" when the env exists but a transient activate returns non-zero). Now: ensure the 'conda' shell function is loaded (source conda.sh if only the binary is on PATH), check the env in 'conda env list', then activate. Clearer not-found message. - install_conda_environment.sh: add '#!/usr/bin/env bash' shebang. It uses bash-only features (BASH_SOURCE, '[ == ]'); running it with sh/dash failed with "Bad substitution" / "unexpected operator" and left SCRIPT_DIR empty. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Change -v/--var default to None. When omitted, open the file and print a formatted table of plottable variables (name, long_name, units, grid type, and Time/Level dependence) so the user can pick a target, then exit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mpas_plot.py: - Replace the opaque "Recovery of [...] failed" RuntimeError (and the raw xarray "no IO backend" traceback) with clear messages: tell the user to pass a mesh file via -gf/--gridfile, and check the gridfile exists and actually carries the connectivity before plotting. - Guard -g/--grid: it only accepts yes/no (draw cell edges). If a file path is passed (the common -g/-gf mix-up), exit with a hint to use -gf instead. Bring mpas_animate.py (native-grid time animations, parallel rendering) over from the stale animation-native-grid branch and fold its README into a single plotting_scripts/README.md covering both mpas_plot and mpas_animate. .gitignore: ignore .DS_Store and generated .gif/.mp4 animations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Merge the two diverged scripts into a single framework. mpas_viz.py draws a still image when one timeline step is selected, or an animation when more than one is, so every option works for both modes. - Global timeline of (file, time_index) entries (--list-times, --tstart/--tend), which also fixes animating a single multi-time file (e.g. sfc_update.nc). - One shared cell renderer (mask-land, dual mesh, friendly -gf errors) plus the animate-only features (wind vectors, --sum-vars/--deaccumulate, custom color scale, --no-coastlines, parallel frame rendering). - mpas_plot.py and mpas_animate.py become thin back-compat shims forwarding to mpas_viz (old commands and imports keep working; --tmin/--tmax aliased). - README rewritten for the single framework, with legacy-command mapping. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n outputs Keep only the ignore for generated .gif/.mp4 under usp-utils/post_proc/ plotting_scripts/ (the direct output of this PR's animation tool). The generic .DS_Store rules are out of scope for the post-processing PR. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an explicit "quote the glob" warning to the time-model section (an unquoted wildcard is expanded by the shell, so only the first file reaches -f), and a step-by-step "animate a run directory" workflow with placeholders (list-times → discover vars → short test range → full parallel animation), including the -gf requirement and the per-cell cost caveat on fine meshes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a unified MPAS native-grid visualization tool (mpas_viz.py) that supports both still plots and time animations on the Voronoi mesh (no regridding), and keeps legacy entrypoints working via thin shims.
Changes:
- Added
mpas_viz.pyas the single plotting/animation framework with a global timeline model, optional land masking, wind vectors, and parallel frame rendering. - Added end-user documentation (
plotting_scripts/README.md) describing workflow, options, and legacy command mappings. - Improved environment tooling and repo hygiene: more robust conda activation logic, bash shebang for conda installer, and new
.gitignoreentries for generated artifacts and stray HOME files.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
usp-utils/setup_environment.sh |
Makes conda detection/activation more robust before running plotting utilities. |
usp-utils/post_proc/plotting_scripts/README.md |
Documents the unified visualization workflow, options, and backward-compatibility behavior. |
usp-utils/post_proc/plotting_scripts/mpas_viz.py |
New unified plotting+animation implementation on the native MPAS grid, with timeline selection and rendering helpers. |
usp-utils/post_proc/plotting_scripts/mpas_plot.py |
Converts the legacy plot script into a shim that re-exports and forwards to mpas_viz.py. |
usp-utils/post_proc/plotting_scripts/mpas_animate.py |
Adds a legacy animate shim that forwards to mpas_viz.py and preserves --tmin/--tmax aliases. |
usp-utils/install_conda_environment.sh |
Adds a bash shebang and clarifies bash-only execution requirements. |
.gitignore |
Ignores generated animations and stray per-user HOME/cache artifacts to prevent accidental commits. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+441
to
+444
| for cell in iterator: | ||
| # Skip land cells when masking is enabled (landmask == 1 over land) | ||
| if landmask is not None and int(landmask.sel(nCells=cell)) == 1: | ||
| continue |
Comment on lines
+462
to
+464
| # Wrap polygons that straddle the +/-180 antimeridian. | ||
| if max(lons) > 170 and min(lons) < -170: | ||
| lons = xr.where(lons >= 170.0, lons - 360.0, lons) |
Comment on lines
+497
to
+498
| if max(lons) > 170 and min(lons) < -170: | ||
| lons = xr.where(lons >= 170.0, lons - 360.0, lons) |
Comment on lines
+667
to
+669
| else: | ||
| print(f"WARNING cannot plot variable with dimensions {da.dims}") | ||
| return |
Comment on lines
+715
to
+719
| if outfile.endswith('.gif'): | ||
| from PIL import Image | ||
| images = [Image.open(f) for f in temp_files] | ||
| images[0].save(outfile, save_all=True, append_images=images[1:], | ||
| duration=int(1000 / fps), loop=0, optimize=False) |
Comment on lines
+46
to
+52
| if conda env list 2> /dev/null | awk '{print $1}' | grep -qx 'cgfd-usp-mpas'; then | ||
| conda activate cgfd-usp-mpas | ||
| echo -e "${INFO} Conda enviroment 'cgfd-usp-mpas' activated" | ||
| else | ||
| echo -e "${WARNING} The 'cgfd-usp-mpas' conda environment was not found. It will not be activated and Python scripts might not work. To install it, run: bash $SCRIPT_DIR/install_conda_environment.sh" | ||
| return 1 | ||
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Before this branch,
usp-utils/post_proc/plotting_scripts/had a single script,mpas_plot.py, which could only draw one still map at a time and had no documentation.This branch turns it into a proper, documented visualization tool for MPAS fields on the native Voronoi grid — with no regridding.
The work is organized into three main improvements:
Improved the plotting script
-gf/--gridfileerror messages.-mlfor ocean-only fields such as SST.Added animation support
-jfor long or heavy runs.Unified plotting and animation into one framework
mpas_viz.py.README.md.The result is that users can now visualize any variable on the native grid as either a still map or an animation. By controlling the available parameters, the tool can also be used to produce publication-ready figures.
Key Features
Visualization controls
Color control:
--cmap--vmin/--vmax--extend-c/--clip, which clips extremes atmean ± 4σfor better color resolutionRegional zoom:
-lat_min-lat_max-lon_min-lon_maxLand masking:
-mlNative dual-mesh rendering
Optional wind-vector overlays:
-u-v_wind--strideCoastline toggle
Derived fields:
--sum-vars--deaccumulateAnimation support
Parallelism for long or heavy animations:
-j N-j -1to use all CPUsEasy by default, powerful when needed
Despite the number of options, the common case remains simple:
Documentation
A new
README.mddocuments the workflow, including:A one-line mental model:
Examples for still maps and animations.
A legacy-command mapping for existing users.
How the Unified Tool Works
Single tool, two modes
mpas_viz.pydraws:This means every option works consistently for both still images and animations.
Global timeline
The tool builds a global timeline of
(file, time_index)entries.Users can:
--list-times.--tstartand--tend, both inclusive.This also supports animating a single multi-time file, such as an
sfc_update.ncfile with 6 time steps.Shared rendering logic
Both still plotting and animation now use one shared cell renderer instead of duplicated logic.
Backward compatibility
mpas_plot.pyandmpas_animate.pyare now thin shims that forward tompas_viz.py.This keeps existing workflows working, including:
mpas_plot.pycommands.mpas_animate.pycommands.The legacy
--tmin/--tmaxoptions are also aliased to--tstart/--tend.Verification
Tested end-to-end on
runs/240km_uniform/.Verified that:
--list-timesrenders correctly.The variable-listing table renders correctly.
A still SST map with
-ml yesmasks the continents.The plot title shows the timestamp.
Animating the single multi-time
sfc_update.ncfile with 6 frames via-j 3produces a valid 6-frame GIF.Both shims produce equivalent output:
mpas_plot.pympas_animate.py --tmin/--tmax