History#

Development#

  • FIX: open_nexradlevel2_datatree(..., incomplete_sweep="pad") pads incomplete sweeps on the nominal azimuth grid from the MSG_31 azimuth_resolution (0.5° / 1.0°, i.e. 720 / 360 rays) instead of the spacing inferred from the jittery measured azimuths (e.g. 0.49° → 735 rays) (GH 396, PR 447) by @syedhamidali

  • DOC: Add Gridding notebook showing how to grid xradar volumes into 3D Cartesian grids with Py-ART (grid_from_radars) and wradlib (vpr.CAPPI and sweep-wise .wrl.ipol.interpolate with vertical interpolation), compare the products (CAPPIs, column maximum, cross-section), with links to further examples (Py-ART, wradlib, Project Pythia, ERAD short courses), and point to it from the README (GH 135, PR 432) by @syedhamidali

  • ENH: New reindex_coord backend kwarg replacing reindex_angle: a nested dict reindex_coord=dict(angle=dict(...), range=dict(...)) reindexes angle (duplicates removed, util.reindex_angle, util.ipol_time) and/or range (new util.reindex_range, analogous to reindex_angle) for all backends and datatree openers (HPL newly supported). reindex_angle still works but emits a FutureWarning; non-dict values now raise a clear error. The Multi-Volume-Concatenation notebook uses it to align the slightly differing ranges of its volumes (GH 407) by @syedhamidali

  • FIX: IRIS site_coords folded southern-hemisphere latitudes (BIN4 > 180°) with the longitude, so latitude came out as longitude - 360; fold the latitude itself (GH 391) by @syedhamidali

  • FIX: ODIM reader no longer fails on quality groups carrying a compound-dtype legend table (ODIM_H5 2.4, e.g. the FMI open archive since 2026-06); the table is attached to the group’s classification variable as CF flag_values / flag_meanings (ODIM 2.3/2.4 Section 6.2 key/value and FMI code/class layouts) instead of being merged as ray data, and a what/legend string attribute is kept as legend (GH 395) by @syedhamidali

  • FIX: open_odim_datatree, open_rainbow_datatree, open_hpl_datatree and open_metek_datatree mapped a list of integer sweeps with an offset of one (sweep=[0] opened the second sweep, or failed for single-sweep files); integer lists now select the same sweeps as single integers and sweep_N names, as in all other backends (GH 412) by @syedhamidali

  • FIX: Fix spacing_is_constant being incorrectly set to false for float32 ranges due to floating-point precision when comparing gate spacing. (PR 402 ) by @mats-knmi

  • DOC: Fix the Multi-Volume-Concatenation notebook for xarray 2026.9 — determine the rotation direction from the time-ordered azimuth differences instead of diff("time") on a sweep whose dimension is azimuth (older xarray silently ignored the missing dimension, newer raises) (PR 406 ) by @syedhamidali

  • FIX: CfRadial1 reader handles a variable number of gates per ray within a sweep — each ray is unpacked by its own ray_n_gates and shorter rays are padded with NaN, instead of assuming the first ray’s gate count for the whole sweep. Also restore RHI detection (elevation as first dimension), which broke in PR 320, and decode sweep_mode after computing so dask-backed inputs keep the full string (GH 322) (PR 405) by @syedhamidali

  • MNT: Refactor the CfRadial1 writer for code quality ahead of v1.0 — descriptive helper names (_main_info_mapper → _extract_root_dataset, _variable_mapper → _combine_sweeps, _calib_mapper → _map_radar_calibration, _sweep_info_mapper → _collect_sweep_metadata), clearer locals, fix the calibs bool/variable name collision, robust history attribute and missing-elevation handling, and a shared _build_cfradial1_dataset reused by xradar.transform.to_cfradial1 to remove duplication (GH 379) by @syedhamidali

  • ENH: When importing ODIM files, extract the global attributes “wmo__id”, “node”, “wmo__originating_centre” and “wmo__wsi” from the ODIM /what/source attribute

  • FIX: Require zarr>=3 so DataTree.to_zarr() works with current xarray (which forwards a zarr_format argument that zarr<3’s open_group() rejects), and fill masked moments (e.g. IRIS VRADH) in the multiple-sweeps-into-volume-scan notebook before writing, since zarr v3 codecs cannot serialize numpy MaskedArray (GH 398) by @syedhamidali

  • FIX: open_nexradlevel2_datatree decodes volumes with interior sweep-index gaps end-to-end — translate sweep label → compact position in NexradLevel2Store.open_store_coordinates so the per-sweep entrypoint stops positionally indexing the compacted msg_31_header (follow-up to PR 362) (GH 366, PR 374) by @aladinor

  • DOC: nexrad_read_chunks notebook now falls back to the open-radar-data fixture when the live S3 listing yields no complete sweep. The guard only caught ValueError, but a listing holding just the start (S) chunk parses fine and returns a DataTree with no sweep groups, so the fallback was skipped and the notebook failed on dtree["sweep_0"] (PR 377) by @aladinor

  • FIX: NEXRAD Level 2 reader drops MSG_31 records when an LDM Compressed Record carries MSG_2 (RDA Status) alongside the 120 radials — NEXRADRecordFile.init_record hard-coded a 120-message stride; per ICD 2620010J §7.3.4 the LDM holds “120 radial messages (type 31) plus 0 or more RDA Status messages (type 2)”. Replace the synthetic mod-120 stride with a byte-walk that detects end-of-LDM by buffer length, with a recnum-position cache for get_data’s per-moment replay (GH 376, PR 377) by @aladinor

  • FIX: ensure to_cfradial2 correctly selects the default storage engine when none is provided, (PR 378) by @chfer

  • MNT: Add cfradial1_sgp_file session fixture and refactor 8 tests in test_util.py/test_accessors.py to share it instead of inlining DATASETS.fetch("sample_sgp_data.nc"). Fixture returns the filename so each test opens its own DataTree, avoiding cross-test mutation (GH 346, PR 347) by @aladinor

  • FIX: IRIS reader rotates the first-loaded moment in each sweep by 1 ray — IrisRawFile._get_ray_record_offsets_and_data initialised j = -1 so the first matching ray of the first-loaded moment was written to raw_data[-1]; affects files without DB_XHDR (data-type bit 0) where DB_DBT becomes the rotated moment (GH 357, PR 375) by @aladinor

  • DOC: Add projection comparison and cartopy map examples to Georeference_TargetCRS notebook by @syedhamidali

  • DOC: Add full-form descriptions for all supported radar formats in README.md by @syedhamidali

  • ADD: India Meteorological Department (IMD) radar NetCDF reader (IMDBackendEntrypoint, open_imd_datatree). IMD stores one sweep per file; open_imd_datatree accepts a single file or a list of files to assemble a multi-sweep volume (GH 368, PR 367) by @syedhamidali

  • FIX: Preserve CfRadial metadata groups during CfRadial1/CfRadial2 transforms, allow to_cfradial2 to reopen root-only engine="cfradial1" datasets, and normalize sweep metadata after map_over_sweeps operations so filtered volumes can be exported to CfRadial1 again (GH 254, GH 322) by @syedhamidali

  • ENH: Expose target_crs on .xradar.georeference() accessor for DataArray, Dataset and DataTree, enabling reprojection via e.g. radar.xradar.georeference(target_crs=4326) (GH 243) by @syedhamidali

  • FIX: set id-token: write in CI testpypi publisher for trusted publishing (GH 364) by @aladinor, (PR 372 ) by @kmuehlbauer

  • MNT: use xarray from PyPI, update pin to xarray=2026.9.0 (last xarray version with Python 3.11) (PR 404 ) by @kmuehlbauer

  • FIX: CfRadial1 export of files with a variable number of gates no longer writes the ragged-layout index variables ray_n_gates/ray_start_index (and sets n_gates_vary to false); the data are written padded to (time, range), and the leftover variables made the file unreadable for xradar and field-less for Py-ART (GH 416) by @syedhamidali

  • FIX: Correct the global attribute assignment in to_cfradial2 (Conventions, version and history are now set on the exported root), and preserve the input DataTree by working on a copy, which is shallow by default; use deepcopy=True for a deep copy (PR 384) by @chfer

  • DOC: Fix the roundtrip example in CfRadial1_Model_Transformation.md by setting first_dim="time" and optional=False when creating dtree3, so the CfRadial1-to-CfRadial2 roundtrip assertion is meaningful and passes (PR 384) by @chfer

  • FIX: IRIS/Sigmet 8-bit types without decoding function (DB_HCLASS, DB_ORAIN, DB_ALBEDO8) are unpacked to one uint8 value per range bin; they were returned as packed int16 words holding two bins each. DB_HCLASS/DB_HCLASS2 get CF flag_masks/flag_values/flag_meanings for the HydroClass bit segments, from the classifiers stored in task_end_info (IRIS Programming Guide 4.4.14) (GH 390, PR 444) by @syedhamidali

  • FIX: CfRadial1 export writes string variables (time_coverage_start, instrument_type, prt_mode, …) as char arrays instead of NC_STRING, which Py-ART could not read, and no longer writes "None" placeholder global attributes or a "None: ..." history (GH 417) by @syedhamidali

  • FIX: CfRadial1 export writes boolean attributes (e.g. NEXRAD mpda_vcp, avset_enabled) as "true"/"false" instead of failing, as netCDF attributes can’t be bool (GH 418) by @syedhamidali

0.12.0 (2026-04-21)#

  • MNT: Unpin xarray, require xarray >= 2026.4.0 in requirements.txt, environment.yml, ci/unittests.yml, and ci/notebooktests.yml by @aladinor

  • MNT: Clarify contributor, team-member, and maintainer roles in the contributing guide, including the pathway to greater project involvement (GH 341) by @kmuehlbauer, (PR 354) by @syedhamidali

  • FIX: open_nexradlevel2_datatree keeps sweeps with interior sweep-index gaps — derive sweep names from actual indices in nex.data instead of range(len(...)) so upstream-dropped interior cuts (e.g. [0..9, 11]) no longer raise KeyError (GH 361, PR 362) by @aladinor

  • ADD: open_cfradial2_datatree reader with grouped CfRadial2 compatibility normalization for common FM301/CfRadial2 naming differences (GH 93, GH 287), (PR 349) by @syedhamidali

  • ENH: Move station coordinates (latitude, longitude, altitude) to root node as coordinates for DataTree coordinate inheritance (GH 331, PR 333) by @aladinor

  • ENH: Add optional_groups parameter (default False) to all open_*_datatree() functions to control inclusion of /radar_parameters, /georeferencing_correction, and /radar_calibration subgroups (GH 331, PR 333) by @aladinor

  • ENH: Skip redundant station coordinate reads for subsequent sweeps in DataTree by passing site_as_coords=False and extracting shared _apply_site_as_coords helper (GH 334, PR 337) by @aladinor

  • ADD: Support list/tuple of chunk files (bytes, file-like, or paths) as input to open_nexradlevel2_datatree for streaming NEXRAD Level 2 data from S3 chunk buckets (PR 332) by @aladinor

  • ADD: incomplete_sweep parameter ("drop"/"pad") to open_nexradlevel2_datatree for handling incomplete sweeps in partial volume data (PR 332) by @aladinor

  • ADD: Notebook example for streaming NEXRAD Level 2 chunks from S3 (nexrad_read_chunks.ipynb) (PR 332) by @aladinor

  • ADD: Comprehensive test suite for chunk list-input and incomplete sweep handling (PR 332) by @aladinor

  • ENH: Expose NEXRAD ICD scan metadata (AVSET/SAILS/MRLE/MPDA/BASE TILT flags, VCP sequencing, per-sweep waveform data) as FM301-compliant user-defined attributes (GH 338, PR 339) by @aladinor

  • FIX: Set indexes and wrap variables in CopyOnWriteArray for ODIM and GAMIC backends, fixes pickle error for BufferedReader (GH 189) by @Ockenfuss, (PR 345) by @kmuehlbauer

  • FIX: Allow passing inherit parameter to apply_to_sweeps / map_over_sweeps to control coordinate inheritance from root node (GH 343, PR 344) by @aladinor

  • FIX: Use open-radar-data fixture as fallback for nexrad_read_chunks.ipynb notebook, replacing dependency on ephemeral S3 chunk data (GH 351, PR 352) by @aladinor

  • MNT: Pin open-radar-data>=0.6.0 for NEXRAD chunk test data (PR 352) by @aladinor

  • MNT: Transform ipynb notebooks to myst markdown notebooks (GH 342, PR 348) by @kmuehlbauer

  • DOC: Link WMO Manual on Codes in README.md (GH 308, PR 353 ) @kmuehlbauer

0.11.1 (2026-02-03)#

0.11.0 (2026-01-12)#

  • ENH: get radar coordinates with given reference system (GH 243) (PR 300) by @egouden

  • ENH: Disable fill value in rainbow reader (GH 103) (PR 290) by @egouden

  • ADD: read nyquist_velocity in ODIM and GAMIC HDF5 files (PR 291) by @katelbach

  • MNT: update and harden CI, add zizmor to precommit, add dependabot (PR 294) by @kmuehlbauer

  • FIX: Return float32 for float types (keep other dtypes) and remove erroneous “units” from time attrs for hpl reader. (GH 296) (PR 297) by @kmuehlbauer

  • MNT: Fix Windows errors in file handling (PR 295) by @egouden

  • MNT: do not overwrite Dataset for Dataset.update (PR 302) by @kmuehlbauer

  • FIX: Properly handle zero and NaN values during IRIS/Sigmet KDP decode. (PR 301) by @billvieux

  • FIX: NEXRAD Level2 backend compatibility with older files and VCP-0 (GH 311, PR 312) by @aladinor

  • FIX: Add explicit compat="no_conflicts", to xr.merge() in _get_subgroup to silence xarray FutureWarning (GH 313, PR 314) by @aladinor.

  • MNT: create individual notebook tests with pytest_generate_tests and use tmp_path-fixture (PR 316) by @kmuehlbauer

  • FIX: Ensure backend closers are available (PR 318) by @kmuehlbauer

  • MNT: Enhance contributing experience (PR 315) by @egouden

  • ENH: Add combine_sweeps function to stack sweeps into a single radar volume with optional time and angle filtering (PR 307) by @egouden

  • FIX: Use time-dimension to stack/unstack CfRadial1 data for variable number of gates, properly handle duplicates (GH 317), (PR 320) by @kmuehlbauer

0.10.0 (2025-07-11)#

  • FIX: Use fixture for making temp file to avoid permission issue on Windows

  • ENH: Supporting for streaming NEXRAD Level 2 data via file-like objects and byte streams. (GH 265) (PR 280) by @aladinor

  • ADD: function to select dataset variables in sweep (GH 104) (PR 254) by @egouden

  • ADD: function to get dataset variables in sweep

  • ADD: function to get metadata variables in sweep

  • FIX: typo in accessors module: Dataarray -> Dataset

  • FIX: Update missing deps for virtualenv environments via “requirements_dev.txt”. (GH 253) (PR 274) by @Steve-Roderick.

  • FIX: Prevent literal timedelta decoding for new xarray versions, fix tests, update pinnings (PR 278) by @kmuehlbauer.

  • MNT: Package and Documentation cleanup (GH 273), PR 284) by @kmuehlbauer.

  • ADD: Support Universal Format (UF) (GH 275) (PR 276) by @kmuehlbauer.

  • ADD: NDPointIndex Notebook example (PR 276) by @kmuehlbauer.

0.9.0 (2025-02-07)#

  • ENH: Adding test to open_datatree function for all backends. Adding “scan_name” to nexradlevel2 datatree attributes (PR 238) by @aladinor

  • FIX: Improving performance of open_nexradlevel2_datatree function and adding tests for sweep parameter. (GH 239) (PR 240) by @aladinor

  • FIX: Keeping attributes at each variable when using open_nexradlevel2_datatree. (GH 241) (PR 242) by @aladinor

  • FIX: Correctly read transition rays in RHI scans (GH 247) (PR 250) by @rcjackson

  • FIX: Correctly open NEXRAD files when split cut mode is enable ({issue} 245) (PR 246) by @aladinor

  • ADD: Example Notebook for assigning geocoords. (GH 243) and (PR 251) by @syedhamidali

  • FIX: DataTree reader now works with sweeps containing different variables (PR 252) by @egouden.

  • FIX: Correct retrieval of intermediate records in nexrad level2 reader (GH 259) (PR 261) by @kmuehlbauer.

  • FIX: Test for magic number BZhX1AY&SY (where X is any number between 0..9) when retrieving BZ2 record indices in nexrad level2 reader (GH 264) (PR 266) by @kmuehlbauer.

  • ENH: Add message type 1 decoding to nexrad level 2 reader (GH 256) (PR 267) by @kmuehlbauer.

  • ENH: Introduce file locks for nexrad level2 and iris backend (GH 207) (PR 268) by @kmuehlbauer.

0.8.0 (2024-11-04)#

This is the first version which uses datatree directly from xarray. Thus, xarray is pinned to version >= 2024.10.0.

  • FIX: Convert volumes to_cfradial1 containing sweeps with different range and azimuth shapes, raise for different range bin sizes (GH 233) by @syedhamidali, (PR 234) by @kmuehlbauer.

  • FIX: Correctly handle 8bit/16bit, big-endian/little-endian in nexrad reader (PHI and ZDR) (GH 230) by @syedhamidali, (PR 231) by @kmuehlbauer.

  • ENH: Refactoring all xradar backends to use from_dict datatree constructor. Test for _get_required_root, _get_subgroup, and _get_radar_calibration were also added (PR 221) by @aladinor

  • ENH: Added pytests to the missing functions in the test_xradar and test_iris in order to increase codecov in (PR 228) by @syedhamidali.

  • ENH: Updated Readme (PR 226) by @syedhamidali.

  • ADD: Added new module transform for transforming CF1 data to CF2 and vice versa (PR 224) by @syedhamidali.

  • Use DataTree from xarray and add xarray nightly run (PR 213, PR 214, PR 215, PR 218) by @kmuehlbauer.

  • ADD: Added new accessor map_over_sweeps for volume operations on DataTrees and a matching decorator (PR 203) by @syedhamidali.

0.7.0 (2024-10-26)#

This is the last version which uses datatree from xarray-contrib/datatree. Thus, xarray is pinned to version 2024.9.0.

  • ADD: Added apply_to_sweeps function for applying custom operations to all sweeps in a DataTree radar volume Implemented by @syedhamidali, (PR 202).

  • ADD: Metek Micro Rain Radar 2 reader by @rcjackson, (PR 200) by @rcjackson.

0.6.5 (2024-09-20)#

  • FIX: Azimuth dimension now labelled correctly for Halo Photonics data (PR 206) by @rcjackson.

  • FIX: do not apply scale/offset in datamet reader, leave it to xarray instead (PR 209) by @kmuehlbauer.

0.6.4 (2024-08-30)#

0.6.3 (2024-08-13)#

0.6.2 (2024-08-12)#

  • FIX: Passing ‘engine’ kwarg in “open_cfradial1_datatree” method to enable fsspec.open when using url (GH 194) by @aladinor, (PR 195) by @aladinor

0.6.1 (2024-08-07)#

0.6.0 (2024-08-05)#

0.5.1 (2024-07-05)#

0.5.0 (2024-03-28)#

0.4.3 (2024-02-24)#

0.4.2 (2023-11-02)#

0.4.1 (2023-10-26)#

0.4.0 (2023-09-27)#

0.3.0 (2023-07-11)#

0.2.0 (2023-03-24)#

  • ENH: switch to add optional how attributes in ODIM format writer (PR 97) by @egouden

  • FIX: add keyword argument for mandatory source attribute in ODIM format writer (PR 96) by @egouden

  • FIX: check for dim0 if not given, only swap_dims if needed (GH 92), (PR 94) by @kmuehlbauer

  • FIX+ENH: need array copy before overwriting and make compression available in to_odim (PR 95) by @kmuehlbauer

0.1.0 (2023-02-23)#

  • Add an example on reading multiple sweeps into a single object (PR 69) by @mgrover1

  • ENH: add spatial_ref with pyproj when georeferencing, add/adapt methods/tests (GH 38), (PR 87) by @kmuehlbauer

  • Docs/docstring updates, PULL_REQUEST_TEMPLATE.md (PR 89) by @kmuehlbauer

  • Finalize release 0.1.0, add testpypi upload on push to main (PR 91) by @kmuehlbauer

0.0.13 (2023-02-09)#

  • FIX: only skip setting cf-attributes if both gain and offset are unused (PR 85) by @kmuehlbauer

0.0.12 (2023-02-09)#

0.0.11 (2023-02-06)#

0.0.10 (2023-02-01)#

0.0.9 (2022-12-11)#

0.0.8 (2022-09-28)#

0.0.7 (2022-09-21)#

0.0.6 (2022-09-19)#

0.0.5 (2022-09-14)#

0.0.4 (2022-09-01)#

Setting up CI workflow and build, @mgrover1 and @kmuehlbauer

0.0.1 (2022-09-01)#

  • First release on PyPI.