Skip to main content

OAFuncs

Oceanic and Atmospheric Functions for Python.

OAFuncs provides utilities for NetCDF files, geoscience arrays, plotting, geographic masks, downloads, file operations, model data, and small workflow tools.

Installation

pip install oafuncs

Optional dependency groups:

data, interp, nc, draw, geo, down, office, parallel, sign, science, all, full

Package Structure

oafuncs
|-- oa_nc.py          NetCDF utilities
|-- oa_data.py        data interpolation helpers
|-- oa_geo.py         geographic and land/ocean mask helpers
|-- oa_draw.py        plotting helpers
|-- oa_cmap.py        colormap helpers
|-- oa_file.py        file operation helpers
|-- oa_date.py        date and timing helpers
|-- oa_down/          download helpers
|-- oa_model/         ROMS and WRF helpers
|-- oa_linux.py       Linux, HPC, and Slurm helpers
|-- oa_office.py      Office document helpers
|-- oa_sign/          website sign-in helpers
`-- oa_tool.py        command, progress bar, email, and parallel helpers

Preserved Historical Version

0.0.99.75 is the last version before the Slurm submission redesign on 2026-10-17. Its archive, version/oafuncs_0.0.99.75/, is a permanent reference for the previous implementation. Preserve it during future cleanup: do not delete, overwrite, or modify it, including when pruning other old versions. The redesigned submission behavior below describes the current source tree.

Public API

oa_nc

Function Purpose
save Write arrays, DataArrays, or Datasets to NetCDF.
merge Merge multiple NetCDF files.
modify Modify a variable value or variable attribute.
rename Rename a NetCDF variable or dimension.
check Check whether a NetCDF file is readable.
convert_longitude Convert longitude coordinates between [-180, 180] and [0, 360].
isel Select NetCDF data by dimension indices.
draw Plot variables from a NetCDF file or xarray object.
compress Apply NetCDF compression.
unscale Decode and remove scale_factor / add_offset storage encoding.

oa_nc.save(write_mode="w") and oa_nc.merge() write to a temporary file before replacing an existing output. Failed writes preserve the previous file; append mode (write_mode="a") still updates the file in place. For NumPy input, preserve_mask_values=True keeps underlying masked values; False writes them as missing values. Explicit missing_value values remain missing even for integer arrays, and all-NaN arrays remain missing rather than 0. merge() preserves raw encoding and input order: units, calendars, non-merged variables and non-merged coordinates must match. It raises ValueError for incompatible inputs rather than converting time units or aligning different grids. oa_nc.rename() checks variable and dimension name conflicts before changing either name, so a conflicting coordinate rename does not leave a partial change.

oa_nc.draw() accepts a NetCDF path, xarray.Dataset, or xarray.DataArray. File-backed workloads use parallel="auto" by default: small batches remain serial, while sufficiently large collections of independent 2D slices use oafuncs.oa_tool.Pex with automatic worker sizing. Use parallel=False to force serial rendering or parallel=True to force Pex. The default output is 300 dpi; set save_dpi=600 when publication-resolution PNG files are needed. On Windows, Pex calls must run below an if __name__ == "__main__": guard. For strongly skewed fields, robust=True displays colors using the 1st–99th percentiles while the title continues to report the complete data range and the clipped color range. The default robust=False preserves the full range.

oa_data

Function Purpose
ensure_list Convert a value to a list.
interp_vertical Interpolate along the fixed z axis in [t, z, y, x] order.
interp_horizontal Interpolate horizontal fields over the fixed y, x axes.

oa_geo

mask_land_ocean() preserves existing xarray dimension coordinates, including x/y grid indices. Longitude and latitude describe mask positions; two-dimensional longitude/latitude arrays must have the same shape.

Function Purpose
earth_distance Calculate great-circle distance between two lon/lat points.
mask_shapefile Mask a 2D field using a shapefile.
mask_land_ocean Keep land or ocean values using a land/ocean mask.
is_land Check whether a lon/lat point is on land.
is_ocean Check whether a lon/lat point is in the ocean.

oa_draw

Function Purpose
fig_minus Format minus signs in axis or colorbar tick labels.
gif Create a GIF from image files.
movie Create a video from image files.
setup_map Configure a Cartopy map.
ticks_symmetric Generate ticks symmetric around a center value.
font_CN Configure Chinese font support for Matplotlib.

oa_draw.gif(frame_duration=0.2) uses seconds (200 milliseconds per frame). Unreadable images are skipped; automatic dimensions come from the first readable image.

oa_cmap

Function Purpose
show Preview a colormap.
to_color Convert a colormap to a list of colors.
create Create a custom colormap from colors or an RGB text file.
get Load a Matplotlib or custom colormap.
random_color Generate a random hex color.

oa_file

Function Purpose
script_dir Return the caller script directory, independent of current working directory.
find Find files by pattern.
link Create symbolic links with wildcard support.
copy Copy files or directories with wildcard support.
move Move files or directories with wildcard support.
rename Rename files by replacing text in filenames.
remove_empty Remove empty folders recursively.
remove Delete files or directories by pattern.
size Return file size in the requested unit.
replace Replace text content by replace_dict and save it to output_path.

Example:

from oafuncs.oa_file import replace

replace(
    input_path="config.txt",
    replace_dict={"old_value": "new_value"},
    output_path=r"D:\run\config.txt",
)

output_path accepts either a file name, such as "result.txt", or an absolute file path. A file name is saved in the input file's directory. Directory-only paths and relative paths containing directories are rejected to avoid ambiguous output. Both direct-text and key-value replacement atomically replace the output path and preserve permission bits. A file link at that path becomes an independent file, leaving its source and other links unchanged. Outputs inside symbolic-link directories or Windows junctions are rejected to avoid modifying source folders. replace() still returns None on success. Read/write, permission and atomic replacement errors now propagate to the caller, including FileNotFoundError, PermissionError and other OSError exceptions; directory-link rejection raises ValueError. Unmatched text or keys retain the existing no-op behavior.

oa_date

Function / Class Purpose
month_days Return the number of days in a month.
hour_range Generate datetime strings at an hourly interval.
adjust_time Offset a base time by a time delta.
timeit Decorator class for timing function execution.

oa_down

Function Purpose
download Download HYCOM data for one time or a time range.
draw_time_range Draw the available HYCOM time range.
download_by_doi Download literature files from DOI lists.
downloader Send a download task to Internet Download Manager.
get_ua Return the default user-agent string for download requests.

Literature downloads require a PDF header and the configured min_size_kb before replacing an existing file. This is a basic content check, not a full PDF integrity check. Each mirror receives its own tries_each_url budget; an HTTP failure moves on to the next mirror and failure records are deduplicated.

For hycom_3hourly.download(), interval_hours for a time range must be a positive multiple of 3. When using IDM, idm_timeout controls how many seconds without a completed valid file are allowed before remaining files are reported as failed; it defaults to 24 hours.

oa_model

Function Purpose
interp Interpolate and remap ROMS data to target lon/lat/depth grids.
header_record Build a WRF little_r header record.
data_record Build a WRF little_r data record.
ending_record Build a WRF little_r ending record.
tail_record Build a WRF little_r tail record.

The little_r helpers retain the existing fixed-width record layout and units. Overlong text fields are truncated to their documented widths; invalid record lengths raise ValueError rather than terminating the caller's Python process.

oa_linux

Function Purpose
patch_slurm Update selected #SBATCH directives in a Slurm script.
submit Submit one Slurm job to one or more eligible partitions.
job_state Query compact live or historical Slurm job state.
is_linux Check whether the current system is Linux.
get_jobid Return an ID only when exactly one current-user active job matches.
scancel_dir Request cancellation of active jobs in one exact directory.

patch_slurm() replaces selected options in place without accumulating blank lines, preserving other options on the same line and trailing comments. Duplicate target options are removed; empty directive lines are dropped and comments are retained as ordinary comments. Resource counts must be positive integers; booleans, strings, fractions and nonpositive counts return False without writing the script. Updates are written to a sibling temporary file and atomically replace the supplied script path, preserving permission bits. A symbolic or hard link at that path becomes an independent file; its source and other links keep their original contents. This also applies to script updates made by submit(). Paths inside symbolic-link directories or Windows junctions are rejected.

from oafuncs import oa_linux

job_id = oa_linux.submit(
    workdir='/path/to/case',
    queues=['cpu_parallel', 'bigmem', 'dcu'],
    max_jobs=50,
    wait_start=False,
    wait_done=False,
)

submit() filters candidates by partition visibility, node count, time limit, and the per-user debug submission cap. It submits exactly one job: multiple eligible queues use a shared request such as #SBATCH -p cpu_parallel,bigmem,dcu; one queue uses a single partition. No replicas, queue switching, or cancellation/resubmission are performed.

Node limits are read dynamically from partition MinNodes/MaxNodes, including for custom queue names. An explicit node count or range must overlap the partition's allowed range; a queue with MaxNodes=1 is therefore excluded from an eight-node request without any name preset. If no -N/--nodes is specified, Slurm chooses the node count from the remaining resource request. On failed or incomplete queries, known single-node queues retain their fallback restriction; unknown limits produce a warning and remain for Slurm to validate. Account/QOS limits are still checked by Slurm, not inferred from partition node limits.

For multiple eligible queues, an existing active #SBATCH --mem is capped at the smallest queue-specific safe request, normally the smallest configured node memory minus 15 GiB (with existing conservative fallback values when the query fails). Lower requests are preserved. If --mem is absent, memory settings are left unchanged, including any --mem-per-cpu directive. A single eligible queue adjusts memory only when an active --mem directive already exists. For either queue count, missing or commented-out --mem directives are never added or enabled; scheduler defaults apply when unset. Explicit --mem-per-cpu or --mem-per-gpu settings are preserved for either queue count; conflicting memory modes are rejected before writing the script. Including debug sets the shared job time limit to 02:00:00.

max_jobs counts the current user's jobs and waits for one submission slot. Both waiting options default to False: the job ID is returned immediately after submission. wait_start=True waits until the job is observed running; wait_done=True waits for confirmed successful completion and takes precedence over wait_start. If a short job finishes between polls, accounting must confirm success before either waiting mode returns its ID. Failure or an unconfirmed final state returns None. A failed live-state query also checks accounting for a confirmed final state; it does not trigger resubmission. The original working directory is restored on exit.

The obsolete race, race_queues, timeout, and wait arguments have been removed. Remove the first three from existing calls and replace wait=True with wait_done=True. Multi-partition submission is internal to submit() and has no separate public function.

Job matching uses one current-user query and includes configuring, completing, suspended and other active states. Path filters accept ~, relative paths and paths containing spaces; matches are exact, with no recursive directory or prefix matching. get_jobid() returns None for zero or multiple matches. Query/parse failures raise RuntimeError in matching and cancellation APIs. The former dir_queued() has been removed. Use get_jobid(path=workdir) when each directory has at most one active job; remember that None also means multiple matches, so it is not a general test for an empty directory.

job_state(job_id) checks accounting when the live state is unavailable and returns compact codes such as PD, R, CD, F or CA. Set history=False for live queries only. No available record returns None; an unresolved query failure raises RuntimeError, and an invalid numeric ID raises ValueError. CD reports scheduler state; completion waiting also validates exit codes.

Use Slurm's scancel job_id for a single job. The former public cancel_job() has been removed. scancel_dir(path) cancels only current-user active jobs whose WorkDir exactly matches the directory; names, shared script locations and child directories do not match. Returned IDs indicate that scancel accepted the request; cleanup may still be in progress. Query or cancellation failures raise RuntimeError.

oa_office

Function Purpose
extract_pptx_notes Extract PowerPoint notes to a Word document.

oa_sign

Function Purpose
sign_in_love_ocean Sign in to 52ocean.
sign_in_meteorological_home Sign in to Meteorological Home.
sign_in_scientific_research Sign in to AbleSci.

oa_tool

On Windows, Pex uses its own spawn context without changing the caller's global multiprocessing start method. Calls still require the main guard.

Pex() chooses workers from CPU limits and current memory headroom: the minimum of host available memory, every visible ancestor cgroup's remaining allowance, and the local Slurm allocation minus current job usage. It leaves 2% headroom unassigned. Clean inactive file cache is conservatively treated as reclaimable; dirty/writeback pages are excluded. Slurm's allocation alone is never reported as free memory. If job-cgroup usage is unavailable, a warning and memory_headroom_gb statistics identify the process-tree fallback, which cannot account for sibling job steps or unmapped file cache.

When task memory is unknown, the first real task runs alone; its result is kept and its incremental memory cost, multiplied by 1.05, sizes the remaining pool without a fixed minimum reservation. The Linux probe subtracts the pre-pool parent PSS baseline from parent-plus-worker PSS, and also measures private worker memory (USS). This excludes inherited shared pages while accounting for new private/shared allocations. Small pools and explicit max_workers caps also use this probe. Before creating the actual pool, headroom is refreshed and its process count is capped using the full per-worker reservation, including startup costs; this also covers all workers started together by Linux fork.

Tasks are submitted individually, with at most one outstanding task per worker, and replenishment pauses when current headroom is insufficient. Each worker reserves only the growth still needed to reach its estimated peak; resident idle workers cannot fund other workers' reservations. Unknown worker slots reserve their full cost, and scheduling uses the largest eligible growth costs because the next worker PID is not guaranteed. USS is preferred for reusable private memory, with conservative PSS/RSS fallbacks. Later observed private worker peaks may raise the estimate, including an explicit reservation that proves too small. Already running tasks are allowed to finish. If no task is running and the next estimated worker cannot fit, MemoryError is raised. Sampling cannot guarantee protection from an unseen instantaneous task peak. For known heavy or heterogeneous tasks, memory_per_worker_gb (also available as OAFUNCS_PEX_MEMORY_PER_WORKER_GB) supplies the per-worker reservation in GiB, including worker overhead, and skips probing. Calls and result order are unchanged; worker counts remain automatic by default.

Function / Class Purpose
run_command Run an external command safely without using a shell.
Pex Parallel executor wrapper with progress and timing. PEx remains as a deprecated compatibility alias until 2026-12-22.
email Send an email.
pbar Create a colored progress bar.

License

MIT License. See LICENSE.txt.

Metadata

Release files for oafuncs 0.0.99.80

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for oafuncs 0.0.99.80
File Size Uploaded Provenance
oafuncs-0.0.99.80.tar.gz 202.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for oafuncs 0.0.99.80
File Interpreter ABI Platform
oafuncs-0.0.99.80-py3-none-any.whl Python 3 none any Details

Total release size: 371.4 kB

Release files / oafuncs-0.0.99.80.tar.gz

Download URL oafuncs-0.0.99.80.tar.gz
Size 202.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0e417f27232640f7dbbe5aaded2ef640282f38ed078ab24047450fe9404c3ca6
BLAKE2b-256 checksum
How to use checksums
85c8df3312a0b5d84425a994bcfbc386077dec8b384c2b4c94f7dce2e04b2b39
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.9

Release files / oafuncs-0.0.99.80-py3-none-any.whl

Download URL oafuncs-0.0.99.80-py3-none-any.whl
Size 169.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cbb5781e0ef98e8d1eacc6c15dd0f512c12faea5f62f6df6b3099b05aa8ee70a
BLAKE2b-256 checksum
How to use checksums
3e74f88a7fdedc9f9e55cc8d9bd8c36e454f730721214662809f4a996b9074de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.9

Security for oafuncs 0.0.99.80

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.99.80 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page