VDAPSEISUTILS is a set of (mostly) Python code that provides easy methods for common tasks in operational volcano seismology.
At the moment, core tasks include:
- VolcanoMap: Plot a basic map and cross section of earthquakes around a volcano.
- ObsPy Catalog & Inventory IO: Import/Export ObsPy Catalog & Inventory formats from Swarm, Earthworm, and NonLinLoc.
Sandbox tasks: (These routines are available, but I may change them significantly before they are stored in core. I am still working on them.)
- Velocity: Load, save, and plot velocity models.
- SwarmMPL: MatPlotLib routines for Swarm-like plots (Helicorders, waveform traces, spectrograms, spectra).
Pending tasks:
- CCMatrix: Create, save, load, and plot cross correlation matrices.
- Waveform statistics: E.g., compute Frequency Index for a list of Stream objects and compare results across events.
- DataSource: A wrapper for ObsPy Clients with a more universal usage (automatically determines Client type).
This package is not yet on PyPI. Clone the repo and use uv to create the environment and install the package (Python 3.11+).
One-time setup
This project uses a named environment vseis311. Set the env path, then sync:
git clone https://github.com/jwellik/vdapseisutils.git
cd vdapseisutils
export UV_PROJECT_ENVIRONMENT=vseis311
uv syncTo make that permanent in this repo (optional), use direnv: run direnv allow once; the project’s .envrc will set UV_PROJECT_ENVIRONMENT=vseis311 whenever you cd here.
Activate and run Python
source vseis311/bin/activate
pythonYou activate by sourcing the script inside the environment directory (vseis311/bin/activate). There is no global activate command that takes a name—that’s Conda’s interface. With Python’s venv (and uv), the environment is just a folder; you always run source <env-dir>/bin/activate (e.g. source vseis311/bin/activate or source .venv/bin/activate if you didn’t set a custom name).
Optional: run without activating: uv run python ..., uv run pytest, etc.
Optional: PyTables (HDF5)
The package does not require tables (PyTables) by default. If you need it, install the system HDF5 library first, then the extra:
- macOS (Homebrew):
brew install hdf5, thenexport HDF5_DIR=$(brew --prefix hdf5)andpip install ".[tables]"(oruv sync --extra tables). - Conda:
conda install hdf5thenpip install ".[tables]".
This package is still in development. If you have trouble with these codes, let me know.
source vseis311/bin/activate
cd gallery
python
>>> from vdapseisutils.gallery import Mapping_tutorial
>>> Mapping_tutorial.main() # graphics forwarding if remoteThis runs a script that reads .arc files from Wy'East/Mt Hood, Oregon and plots them on a map and cross sections. See the Gallery for more examples and usage.
Map classes are implemented under vdapseisutils.core.maps (e.g. map.py, volcano_figure.py). The module vdapseisutils.core.maps.maps is deprecated: importing it emits DeprecationWarning and re-exports the same symbols for now; it will be removed in a future release. Prefer from vdapseisutils.core.maps import Map (and from vdapseisutils.core.maps.utils import prep_catalog_data_mpl, etc.). Backend-neutral compute lives under vdapseisutils.compute (see the package docstring there).
Catalog points and origins: Use vdapseisutils.compute.catalog.prepare_catalog_points (or prepare_catalog_points_from_time_format for legacy time_format strings) for matplotlib-free tables of hypocenter data. vdapseisutils.utils.obspyutils.catalog.origin.get_primary_origin selects the QuakeML preferred origin when present, otherwise the first origin—the same rule used for VCatalog event-rate extraction, scatter maps, and catalog2txyzm by default. Pass origin_policy="last" to catalog2txyzm if you need the old “last origin in the list” behavior.
Maps matplotlib style (no import-time rc): Pure style dicts live in vdapseisutils.core.maps.defaults_constants. Importing that module does not load Matplotlib or change rcParams. To apply the maps theme globally, call vdapseisutils.core.maps.defaults.register_maps_mpl_style() once (e.g. at app startup). Map constructors (Map, CrossSection, VolcanoFigure, TimeSeries) call ensure_maps_mpl_style() so figures still get the intended defaults when those classes are used without a prior explicit registration.
Maps / volcano layout (narrative + examples, API v1 §11): See docs/maps_volcano_api_v1.md for how Map, VolcanoFigure, CrossSection, TimeSeries, and MagLegend fit together, import paths, register_pyplot() (plt.eqmap / plt.volcano), and catalog compute via vdapseisutils.compute.catalog.prepare_catalog_points. Runnable offline examples from the repo root: python examples/map_minimal.py, python examples/volcano_figure_layout.py, python examples/cross_section_standalone.py (or uv run python …).
Waveform and spectrogram compute: Shared, backend-neutral helpers live in vdapseisutils.compute.waveforms: prepare_waveform_series returns a WaveformSeriesResult (time axis and data); compute_spectrogram returns a SpectrogramResult (frequency, time offset, power) using the SciPy spectrogram path aligned with Swarm-style plots. vdapseisutils.core.swarmmpl (including the v3 time-axis stack) calls these helpers then draws; use the same APIs if you need arrays without Matplotlib.
If you still use older import paths (e.g. core.maps.maps), read CHANGELOG.md and the policy sections §8–§9 (and §13.4–§13.5) in .local/api-v1-coord/API_V1_CANONICAL.md if you keep a local copy of that doc.
You can attach VDAPSeisUtils figure constructors to Matplotlib’s pyplot module (API v1 section 3 in .local/api-v1-coord/API_V1_CANONICAL.md):
import matplotlib.pyplot as plt
import vdapseisutils.plot.mpl as vsmpl
vsmpl.register_pyplot()
fig = plt.helicorder(...) # or plt.clipboard / plt.eqmap / plt.volcano / plt.swarmAfter register_pyplot(), those names construct the corresponding project types (Helicorder, clipboard / SwarmFigure, Map, VolcanoFigure; plt.swarm matches plt.clipboard—see vdapseisutils.plot.mpl).
Swarm-style plotting (multi-trace clipboard, helicorder, time axes / panels) has one canonical import path: vdapseisutils.plot.swarm. Implementations live under vdapseisutils.core.swarmmpl (clipboard.py, panel.py, timeaxes.py, heli.py, …). Policy notes are in .local/api-v1-coord/API_V1_CANONICAL.md §8 (Swarm consolidation).
Canonical (new code):
from vdapseisutils.plot.swarm import (
Helicorder,
Clipboard, # legacy factory → ClipboardClass / SwarmFigure
ClipboardClass,
SwarmFigure, # alias of ClipboardClass (API v1 §3)
TimeAxes,
Panel,
SwarmClipboard, # v3 panel clipboard (distinct from the legacy Clipboard factory)
)Core module (same types as plot.swarm):
from vdapseisutils.core.swarmmpl.clipboard import Clipboard, ClipboardClass, SwarmClipboard
from vdapseisutils.core.swarmmpl import Panel, TimeAxesPrefer clipboard_figure if you want an explicit name for the legacy factory; it is the same callable as Clipboard.
Swarm runnable on-ramp (API v1 §11-style): For a short, offline script that constructs Helicorder and SwarmClipboard on synthetic waveforms (no FDSN), run from the repo root: python examples/swarm_clipboard_minimal.py (or uv run python …). That mirrors how map workflows point to examples/map_minimal.py and friends; deeper layout and naming notes remain under Pyplot helpers (register_pyplot) and vdapseisutils.plot.swarm / core/swarmmpl source.
