Tools to aid some tasks of working with the netcdf4-python library
Project description
nc4-tools
A Python package combining a number of netCDF4 tools useful in various parts of my workflow.
Contents
NCDatasetclass - An extension of netCDF4.DatasetNCTemplateclass - Dataset creation from a CDL fileNCVarSlicerclass - NetCDF variable slicerduplicate_varmodule - Variable duplication functions
NCDataset class - An extension of netCDF4.Dataset
NCDataset is a subclass of netCDF4.Dataset from the netCDF4 python library. The primary goal of NCDataset has been to make dataset objects reusable--that is to be able to re-open a closed dataset without re-specifying all the opening arguments.
Features of NCDataset
- Track dataset path and initialization args (e.g.
mode,diskless,clobberetc.) for re-use of the dataset object in multiplewithblocks. - If the dataset is opened in mulitple
withblocks, do not close it until leaving the outermostwithblock. (Note that even if the Dataset was opened before outermostwithblock, it will close when leaving it.) - Each dataset gets an
auto_maskattribute that sets theset_auto_maskvalue on the dataset when the dataset is opened. By default, this is set toFalse(in contrast withnetcdf4.Dataset), but may be changed by the module-levelauto_maskvariable. keepopen=Falsearg allows the dataset object to be created/opened but then closed immediately (for later use in awithblock)update_args(**kwargs)can be used to update calling keyword args (though not the path to the dataset.)__call__(**kwargs)callsupdate_args(**kwargs).
open(**kwargs)opens the dataset (if closed), updating the calling arguments with**kwargs. If the dataset is already open it does nothing.- To help prevent accidental dataset overwrite:
- After initialization, if
modeis set to"w"it is automatically switched to"a"unlessclobberis set toTrue. - If
clobberis set toTrueat any point it reverts toFalseafter the object is closed.
- After initialization, if
__str__includes the dataset path and the open/closed state in addition to the stuff fromnetcdf4.Dataset__getitem__and__getattr__first check if the dataset is open and raise anNCDatasetErrorif the dataset is closed. Also, thedimensions,variables, andgroupsproperties first check if the dataset is open (unlessfailfastisFalse).
Examples
>>> from nc4_tools.ncdataset import NCDataset
>>> ds = NCDataset("example.nc", mode="w", keepopen=False, diskless=True, persist=True)
>>> print(ds)
NCDataset[netCDF4.Dataset]
kwargs: {'diskless': True, 'persist': True, 'mode': 'w', 'clobber': False}
(closed)
>>> # Since mode was "w", mode is now automatically "a" (unless we set clobber=False)
>>> # Changes to the kwargs can be made with update_params or just __call__
>>> with ds(diskless=False):
... # Can augment the netCDF4.Dataset here, just like netCDF4.Dataset
... ds.createDimension("time", 1024)
... print(ds)
...
NCDataset[netCDF4.Dataset]
kwargs: {'diskless': False, 'persist': True, 'mode': 'a', 'clobber': False}
<class 'hpx_radar_recorder.ncdataset.NCDataset'>
root group (NETCDF4 data model, file format HDF5):
dimensions(sizes): time(1024)
variables(dimensions):
groups:
>>> # The dataset remains open in nested context managers
>>> print(f"DATASET NOT YET OPENED, ds.isopen(): {ds.isopen()}")
>>> with ds:
... print(f"OUTER with BLOCK, ds.isopen(): {ds.isopen()}")
... with ds:
... print(f"INNER with BLOCK, ds.isopen(): {ds.isopen()}")
... print(f"EXITED INNER with BLOCK, ds.isopen(): {ds.isopen()}")
... print(f"EXITED OUTER with BLOCK, ds.isopen(): {ds.isopen()}")
DATASET NOT YET OPENED, ds.isopen(): False
OUTER with BLOCK, ds.isopen(): True
INNER with BLOCK, ds.isopen(): True
EXITED INNER with BLOCK, ds.isopen(): True
EXITED OUTER with BLOCK, ds.isopen(): False
NCTemplate class - Dataset creation from a CDL file
NCTemplate is a tool to create a template NetCDF4 dataset from a template NetCDF
CDL file using the ncgen
command-line utility (must be installed on the OS).
NCTemplate is a subclass of NCDataset and thus includes the context-manager features of that class.
Usage
from nc4_tools.nctemplate import NCTemplate
with NCTemplate("template.cdl") as tmpl_ds, NCDataset("new_ds.nc", mode="w") as new_ds:
# Add code here to copy dimensions, variables, and attributes from tmpl_ds to new_ds
pass
NCVarSlicer class - NetCDF variable slicer
Introduction
In NetCDF schemas such as the CFRadial Format, one or more virtual dimensions may exist that subdivide a real dimension. In this situation, ancillary variables must be provided to specify the start and stop indices in the real dimension that are the boundaries of each unit in the virtual dimension.
In the case of the CFRadial format the sweep dimension subdivides the time dimension, and the sweep_start_ray_index and sweep_end_ray_index variables specify the start and end boundaries, in the time dimension, of each sweep.
Once created, an NCVarSlicer object may be called with __getitem__ (i.e. []) syntax.
If a single integer index is provided, a single slice object is returned corresponding to
the real dimension bounds of that index in the virtual dimension. If a slice is provided,
then a list of slice objects is returned corresponding to each selected index in the
virtual dimension.
Example Usage
Given:
- A netCDF file
dataset.ncwith timeseries data- Dimensions
timeandsample_group - Data variable
intensity(time) - Group indexing variables
group_start_index(sample_group)andgroup_end_index(sample_group)
- Dimensions
import netCDF4
from nc4_tools.ncvarslice import NCVarSlicer
with netCDF4.Dataset("dataset.nc") as ds:
group_slicer = NCVarSlicer(ds["group_start_index"], ds["group_end_index"])
for slc in group_slicer:
# Work with each sample group
sample_group_data = ds["intensity"][slc]
Equivalent to:
import netCDF4
with netCDF4.Dataset("dataset.nc") as ds:
for i in range(ds.dimensions["sample_group"].size):
a = ds["group_start_index"][i]
b = ds["group_end_index"][i] + 1
# Work with each sample group
sample_group_data = ds["intensity"][a:b]
CfRadial Example
import netCDF4
from nc4_tools.ncvarslice import NCVarSlicer
with netCDF.Dataset("dataset.nc") as ds:
for slc in NCVarSlicer(ds["sweep_start_ray_index"], ds["sweep_end_ray_index"]):
# slc is a slice object providing the indices of the time dimension for a single radar
# sweep
sweep_power = ds["PWR"][slc][:] # power values for all rays in sweep (at every range)
sweep_times = ds["time"][slc] # timestamps of the rays in the sweep
sweep_azimuths = ds["azimuth"][slc] # azimuths of the rays in the sweep
# Or, to process groups of sweeps:
sweeps_per_group = 4
sweep_slicer = NCVarSlicer(ds["sweep_start_ray_index"], ds["sweep_end_ray_index"])
for slc_i in range(0, len(varslicer), sweeps_per_group):
sweep_slices = sweep_slicer[slc_i : slc_i + sweeps_per_group]
... # sweep_slices is a list of slices for each sweep in the group
... # perhaps do parallel processing on four sweeps at a time
duplicate_var module - Variable duplication functions
get_createVar_kwargs()
Use an existing netCDF4.Variable to get the keyword arguments for netCDF4.Dataset.createVariable to create an identical variable.
contains_vlen()
Determine if a netCDF4.Variable.datatype is or contains (e.g. in a CompoundType) a
variable-length datatype. Useful for determining if compression may be applied to a
variable.
duplicate_var()
Use an existing variable ina netCDF4.Dataset to create a variable in a new dataset with
the same or similar filters and attributes. I use this to streamline the process of
creating a new dataset based on an NCTemplate dataset (which in turn, is based on a
CDL file.)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nc4_tools-1.2.0.tar.gz.
File metadata
- Download URL: nc4_tools-1.2.0.tar.gz
- Upload date:
- Size: 77.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"LMDE","version":"6","id":"faye","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0328a96c3333c5ba31b2e5b3e498094023b47ce77cfeac7323d11d8859b8df09
|
|
| MD5 |
2cb39011905aaaebde66ce5938ff78f4
|
|
| BLAKE2b-256 |
9057cbcf7393a0c8a490770deecca36fa6ee6f25b89dbc91677eb2e465c0dc63
|
File details
Details for the file nc4_tools-1.2.0-py3-none-any.whl.
File metadata
- Download URL: nc4_tools-1.2.0-py3-none-any.whl
- Upload date:
- Size: 17.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"LMDE","version":"6","id":"faye","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1888dd4fb4a60c8f56e6d0c26de8ab789b0c75c068b7cc1ac0b7a81c5adfb41a
|
|
| MD5 |
712dd8f9474604c4a50ad7470e6724f5
|
|
| BLAKE2b-256 |
38fea5c11abb9560153628a0f8ba64aba393005b91f1ab38ae58c9a652f7e5b2
|