{"id":51058644,"url":"https://github.com/rhettadam/mdsview","last_synced_at":"2026-06-22T23:30:41.943Z","repository":{"id":364868238,"uuid":"1269422032","full_name":"rhettadam/mdsview","owner":"rhettadam","description":"Browse, plot, and compare MITgcm MDS binary output from the CLI or an optional GUI.","archived":false,"fork":false,"pushed_at":"2026-06-14T21:12:23.000Z","size":651,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-14T22:20:42.873Z","etag":null,"topics":["binary-data","cli","climate-modeling","matplotlib","mds","mitgcm","ocean-modeling","python","scientific-visualization"],"latest_commit_sha":null,"homepage":"https://rhettadam.github.io/mdsview/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rhettadam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-14T17:37:31.000Z","updated_at":"2026-06-14T21:16:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rhettadam/mdsview","commit_stats":null,"previous_names":["rhettadam/mdsview"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/rhettadam/mdsview","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhettadam%2Fmdsview","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhettadam%2Fmdsview/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhettadam%2Fmdsview/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhettadam%2Fmdsview/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rhettadam","download_url":"https://codeload.github.com/rhettadam/mdsview/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhettadam%2Fmdsview/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34669839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-22T02:00:06.391Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binary-data","cli","climate-modeling","matplotlib","mds","mitgcm","ocean-modeling","python","scientific-visualization"],"created_at":"2026-06-22T23:30:39.486Z","updated_at":"2026-06-22T23:30:41.935Z","avatar_url":"https://github.com/rhettadam.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://raw.githubusercontent.com/rhettadam/mdsview/main/docs/images/logo.png\" alt=\"mdsview logo\" width=\"280\"\u003e\n\nBrowse, plot, and compare MITgcm MDS (`.data`/`.meta`) binary output. Use the CLI on a cluster or the optional GUI on your laptop or PC.\n\n[![PyPI version](https://img.shields.io/pypi/v/mdsview.svg)](https://pypi.org/project/mdsview/)\n[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\n**Site:** [rhettadam.github.io/mdsview](https://rhettadam.github.io/mdsview/)\n\n[MITgcm](https://mitgcm.org/) (MIT General Circulation Model) is a widely used ocean and climate model. A typical run writes out many 3-D fields (temperature, salinity, sea surface height, velocities) at regular time steps, often from MPI jobs on a cluster. The default binary format is **MDS**: each field is a **`.meta`** file (dimensions, precision, iteration) plus a **`.data`** file (raw array, usually big-endian float32). Tiled MPI output adds more filename suffixes but the same basic layout.\n\nAfter a run you usually have a directory with hundreds or thousands of these file pairs and no built-in viewer. MITgcm ships [`MITgcmutils`](https://github.com/MITgcm/MITgcm/tree/master/utils/python/MITgcmutils) for reading and writing MDS in Python, but you still need scripts to list what's there, pick an iteration and level, plot a slice, subtract two snapshots, or export subsets. mdsview fills that gap: catalog a run folder without loading `.data`, plot 2-D slices with grid coordinates, diff two snapshots (including cross-run), export to NetCDF, extract subsets, build time series, and save figures from the terminal or a local GUI.\n\nFor huge LLC runs or lazy xarray loading, use [`xmitgcm`](https://xmitgcm.readthedocs.io/). mdsview targets quick inspection of run directories.\n\n## Install\n\nFrom [PyPI](https://pypi.org/project/mdsview/):\n\n```bash\npip install mdsview              # CLI (headless)\npip install \"mdsview[gui]\"       # + desktop GUI (CustomTkinter)\n```\n\nFrom source:\n\n```bash\ngit clone https://github.com/rhettadam/mdsview.git\ncd mdsview\npip install -e .\npip install -e \".[gui]\"\n```\n\nOn Windows, if `mdsview` is not on PATH:\n\n```bash\npython -m mdsview.cli info -d C:\\path\\to\\run\n```\n\nRequires Python 3.9+, NumPy, matplotlib, MITgcmutils, cmocean, Pillow, and netCDF4 (for `export`). GUI needs CustomTkinter.\n\n## Quick start\n\n```bash\nmdsview info -d /path/to/run\nmdsview plot -v T -i 480 -l 4 -d /path/to/run\nmdsview plot -v T -i 480 -l 4 --save-figure t.png --no-show -d /path/to/run   # headless\nmdsview gui -d /path/to/run\n```\n\n`-d FOLDER` is the run directory (default: `.`). `-v NAME` is the field prefix (`T`, `S`, `Eta`, …). Most commands accept `--json`. Run `mdsview COMMAND --help` for options.\n\n## Sample data\n\nSynthetic run directories for testing without MITgcm:\n\n```bash\nmdsview generate-sample -o sample_data --preset demo\n```\n\nSee `sample_data/SAMPLE_README.txt` after generation. Other presets and options: `mdsview generate-sample --help`.\n\n## CLI\n\n### `info`\n\nList variables or show metadata. Reads `.meta` only, safe with thousands of snapshots.\n\n```bash\nmdsview info\nmdsview info -v T\nmdsview info -v T --show-meta\nmdsview info -v T --json\n```\n\n### `plot`\n\nOne 2-D slice. With `--level`, reads a single horizontal slab, not the full volume.\n\n```bash\nmdsview plot -v T -i 480 -l 4\nmdsview plot -v Eta -i last\nmdsview plot -v T -i 0 -l 10 --cmap haline --vmin 0 --vmax 30 --save-figure out.png --no-show\nmdsview plot -v T -i 0 --no-coords    # index axes, not XC/YC\n```\n\n### `diff`\n\n`field(LATER) − field(EARLIER)`. Default is one slice; `--save-field` without `--level` loads full volumes.\n\n`-d` is the **later** run (minuend). `--dir-b` / `--earlier-dir` is the **earlier** run when comparing two model directories at the same (or different) iterations.\n\n```bash\nmdsview diff -v T --later 2520 --earlier 0 -l 20\nmdsview diff -v T --later 2520 --earlier 0 -l 20 --plot --save-figure diff.png --no-show\nmdsview diff -v T --later 2520 --earlier 0 --save-field T_diff\nmdsview diff -v T 480 0 -l 4          # positional iters also work\nmdsview diff -v T --later 2520 --earlier 2520 -l 20 -d /scratch/warm --dir-b /scratch/ref\n```\n\n### `export`\n\nWrite variables to NetCDF with CF-style `time`, `depth` (when present), and horizontal `y`/`x` coordinates (or `lat`/`lon` for geographic degree grids). Optional 2-D `xc`/`yc` arrays are included when grid files exist. All variables in one file must share the same MDS shape (e.g. `T` and `S` together, not `T` and `Eta`).\n\n```bash\nmdsview export -v T,S -o run.nc --iterations all\nmdsview export -v T -o surface.nc --iterations all --levels 0\nmdsview export -v T -o patch.nc --iterations last --region 10,50,20,40\n```\n\nShared selection flags: `--iterations` (`all`, `last`, `0,360`, `0:1200:120`), `--levels`, `--region I0,I1,J0,J1`, `--rec`, `--json`.\n\n### `extract`\n\nCopy snapshots to a new folder as MDS files. Reads one iteration at a time.\n\n```bash\nmdsview extract -v T -o subset/ --iterations 0:1200:120 --levels 0:10\nmdsview extract -v T -o patch/ --iterations all --region 100,200,50,150\nmdsview extract -v Eta -o eta_only/ --iterations last\n```\n\nUses the same `--iterations`, `--levels`, and `--region` flags as `export`.\n\n### `timeseries`\n\nBuild a CSV or JSON time series without loading full volumes. A line plot opens by default.\n\n```bash\nmdsview timeseries -v T -l 4 --iterations all --at 40,30 -o point.csv\nmdsview timeseries -v T -l 10 --iterations all --box 0,80,0,60 -o box.csv\nmdsview timeseries -v Eta --iterations all --save-figure ssh.png --no-show\nmdsview timeseries -v T -l 0 --iterations 0:480:120 --json --no-plot\n```\n\nDefault reduction is a domain mean over the chosen level. For 3-D fields without `-l`, mid-depth is used. Use `--at I,J` for a point, `--box I0,I1,J0,J1` for a box mean, `--save-figure` / `--no-show` for headless plots, and `--no-plot` for data only.\n\n### `combine`\n\nStack iterations into one array. Loads every listed iteration; use for small tests only.\n\n```bash\nmdsview combine -v T --iterations 0,360,720 --save-field T_stack\n```\n\n### `generate-sample`\n\nCreate synthetic `.data`/`.meta` for tests. See [Sample data](#sample-data).\n\n### Plot options\n\nUsed by `plot` and `diff`:\n\n- `-l`, `--level K`: vertical index (0 = top)\n- `--cmap`: default `thermal` (plot) or `balance` (diff); matplotlib + cmocean names\n- `--vmin`, `--vmax`\n- `--save-figure FILE`, `--no-show`\n\nDiff plots use a symmetric diverging scale. Full list: `mdsview/colormaps.py`.\n\n## GUI\n\n```bash\npip install \"mdsview[gui]\"\nmdsview gui -d /path/to/run\n```\n\n![Main window](https://raw.githubusercontent.com/rhettadam/mdsview/main/docs/images/gui-overview.png)\n\nRun directory at the top. Left rail switches Catalog, Field, and Grid panels; controls sit beside the plot. Stats (min, mean, max, std) update with each field.\n\nLarge runs (many iterations or variables) are indexed in the background: the catalog lists snapshot counts without reading every `.meta` file up front. Use **Field** to plot one 2-D slice at a time; use **`mdsview diff`** on the CLI for snapshot differences.\n\n![Catalog](https://raw.githubusercontent.com/rhettadam/mdsview/main/docs/images/gui-catalog.png)\n\nLists every variable in the run. Selecting one loads metadata below; double-click or **Plot selected** opens it in Field.\n\n![Field + playback](https://raw.githubusercontent.com/rhettadam/mdsview/main/docs/images/gui-field-playback.png)\n\nPick variable, iteration, and level. Sliders auto-refresh the plot. Footer controls step through time or export a GIF.\n\n![Grid](https://raw.githubusercontent.com/rhettadam/mdsview/main/docs/images/gui-grid.png)\n\nPreview XC/YC (or other grid files) and optionally overlay grid lines on field plots.\n\nTop bar: **Open** (`Ctrl+O`), **Refresh** (`Ctrl+R`), **PNG** (`Ctrl+S`), **GIF** (export dialog). Matplotlib pan/zoom sits under the plot. For remote sessions (X2GO, SSH with X forwarding), prefer the CLI; the GUI is tuned for local use.\n\n## HPC / batch\n\nCLI uses the Agg backend by default (no display). Use `--save-figure` and `--no-show`:\n\n```bash\nmdsview info -d /scratch/run001\nmdsview plot -v T -i last -l 20 -d /scratch/run001 --save-figure t.png --no-show\nmdsview diff -v T --later 2520 --earlier 0 -l 20 -d /scratch/run001 --json\nmdsview export -v T,S -o run.nc -d /scratch/run001 --iterations all --levels 0\nmdsview timeseries -v Eta -d /scratch/run001 --iterations all -o ssh.csv --no-plot\n```\n\nExit codes: `0` ok, `1` error, `2` bad args, `130` interrupt. Errors go to stderr. Tracebacks: `MDSVIEW_DEBUG=1`.\n\n### Memory\n\n- `info`: `.meta` filenames only\n- `plot` / `diff` with `-l`: one slab per snapshot\n- `export`, `extract`, `timeseries`: one iteration (or slab) at a time\n- `diff --save-field` (no level): full volume; `combine`: all listed iters in RAM\n\n## Python API\n\n```python\nfrom mdsview import io, ops, plotting\n\nslab = io.read_level_slice(\"/path/to/run\", \"T\", 480, level=4)\ndiff2d, meta = ops.diff_slice(\"/path/to/run\", \"T\", later=480, earlier=0, level=4)\ndiff2d, meta = ops.diff_slice(\"/warm\", \"T\", 2520, 2520, level=20, data_dir_b=\"/ref\")\nplotting.plot_field(\"/path/to/run\", \"T\", 480, level=4, save=\"t.png\", show=False)\n```\n\n## Limitations\n\n- Standard MDS only, not `pkg/mnc` tiles (use `gluemnc` first)\n- No 3-D volume rendering; LLC unfolding is partial (needs XC/YC in the run dir)\n\n## License\n\nMIT License. See [LICENSE](LICENSE). Copyright (c) 2026 Rhett R. Adam.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhettadam%2Fmdsview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frhettadam%2Fmdsview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhettadam%2Fmdsview/lists"}