Skip to main content

xradar

PyPI Version Conda Version DOI CI Build distribution RTD Version

Xradar includes all the tools to get your weather radar into the xarray data model.

How to cite Xradar

This project provides a Zenodo badge with a DOI for easy citation — click the badge above to get the official citation and permanent archive.

GitHub also offers a “Cite this repository” button near the top right of this page, where you can quickly copy the citation in various formats like APA and BibTeX.

In the rendered documentation, you will find the full citation below.

About

At a developer meeting held in the course of the ERAD2022 conference in Locarno, Switzerland, future plans and cross-package collaboration of the openradarscience community were intensively discussed.

The consensus was that a close collaboration that benefits the entire community can only be maximized through joint projects. So the idea of a common software project whose only task is to read and write radar data was born. The data import should include as many available data formats as possible, but the data export should be limited to the recognized standards, such as ODIM_H5 and CfRadial.

As memory representation an xarray based data model was chosen, which is internally adapted to the forthcoming standard CfRadial2.1/FM301. FM301 is enforced by the Joint Expert Team on Operational Weather Radar (JET-OWR). Information on FM301 is available at WMO as WMO CF Extensions and is described in the WMO Manual on Codes.

Any software package that uses xarray in any way will then be able to directly use the described data model and thus quickly and easily import and export radar data. Another advantage is the easy connection to already existing open source radar processing software.

Status

Xradar is considered stable for the implemented readers and writers which have been ported from wradlib. It will remain in beta status until the standard is finalized and the API as well as data model will move into stable/production status.

Features

Import/Export Capabilities

Import-Only Capabilities

  • DataMet — DataMet weather radar
  • Furuno — Furuno weather radar
  • Gamic — GAMIC HDF5
  • HPL — Halo Photonics Lidar
  • IMD — India Meteorological Department
  • Iris — Vaisala IRIS/Sigmet
  • MRR — Micro Rain Radar (METEK)
  • NexradLevel2 — NEXRAD WSR-88D Level 2
  • Rainbow — LEONARDO (formerly Selex/Gematronik) Rainbow
  • UF — Universal Format

Data Transformation and Alignment

  • Georeferencing (AEQD projection)
  • Angle Reindexing
  • Format Transformation support to CfRadial1 and CfRadial2

Contributors

Thanks to our many contributors!

Contributors

History

0.13.0 (2026-10-21)

This release brings a unified open_datatree interface (xd.open_datatree(file, engine=...) / xr.open_datatree) for all 13 backends, including the new IMD reader, and engine discovery so that formats unknown to xarray (NEXRAD Level II, IRIS, Rainbow, UF, ...) open without engine. IRIS moment decoding now follows the IRIS Programming Guide (2024), and numerous fixes improve sweep selection, file handling (close() releases files for every backend) and CfRadial and ODIM import and export, including repeatable CfRadial1/2 roundtrips. The CfRadial1 export writes CfRadial 1.4 metadata (version, Conventions with the sub-conventions, the names of the calibration tables), keeps rays which share a timestamp, writes strings as char arrays (which Py-ART can read) and boolean attributes as "true"/"false", and raises a clear error for volumes whose sweeps have different range geometry; to_odim builds what/source from the identifiers of the data it read. New documentation and notebooks cover gridding, georeferencing, format mappings and engine discovery, and the project now has an AI Usage Policy.

@aladinor and @syedhamidali are the main contributors to this release, with contributions from @kmuehlbauer, @zssherman, @mats-knmi, @chfer and @Jah-yee.

Please note: xradar now requires Python >= 3.12 and zarr >= 3. The open_*_datatree functions and reindex_angle are deprecated (use open_datatree(..., engine=...) and reindex_coord). ODIM TH/TV are now read as DBTH/DBTV, and IRIS no-data bins are NaN instead of values such as -32 dBZ.

  • DOC: Add AI Usage Policy (docs/ai_policy.md) adapted from xarray's policy, with xradar-specific guidance for CI, packaging, and dependency changes, copyright and licensing, and disclosure of AI usage ({pull}363) by @aladinor
  • FIX: Dataset.close() and DataTree.close() release the file for every backend, also after georeference()/add_crs() and when opening fails (most backends left files open until garbage collection, which can crash HDF5); CfRadial1 caches its data once ({issue}471, {issue}502, {pull}472) by @aladinor
  • MNT: CI unit tests use released xarray again, and test jobs time out after 30 minutes ({issue}495, {pull}510) by @aladinor
  • FIX: DataMet, Furuno, IRIS (also open_iris_datatree) and Metek accept pathlib.Path (as HPL and Rainbow do), UF reads datatrees from file-like objects (sweep discovery consumed the object without rewinding), and the CfRadial1 backend applies fix_second_angle to sweep groups in open_dataset and open_datatree (it was accepted but ignored) ({pull}509) by @aladinor
  • CI: Updated immutable hashes to newer versions and added missing trailing version comments ({pull}511) by @zssherman
  • FIX: the deprecated open_*_datatree functions and xd.open_datatree go through xr.open_datatree again, so chunks, cache and backend_kwargs work as before {pull}335, legacy optional=False no longer raises, and iris, rainbow, furuno and datamet sweeps keep their range index; optional_groups=True no longer copies latitude/longitude/altitude into /radar_parameters and /georeferencing_correction; the reindex_angle FutureWarning is emitted once and points at the caller; open_uf_datatree has its signature and docstring back; the CfRadial1 and CfRadial2 backend option for the netCDF reader is netcdf_engine (engine still works in open_cfradial1_datatree and open_cfradial2_datatree), since engine collided with xarray's own argument; as in xr.open_datatree, a keyword given both directly and in backend_kwargs takes the backend_kwargs value, and passing both site_coords and site_as_coords raises TypeError; NEXRAD and UF sweeps get a range index like the other engines, and both honour first_dim given in backend_kwargs; the CfRadial2 backend stays lazy and close() releases the file ({issue}481, {pull}484) by @aladinor and @kmuehlbauer
  • DOC: multiple-sweeps-into-volume-scan notebook builds a three-volume tree (radar_files[:12]) instead of six, saving about a minute of Read the Docs build time, which was running close to the 15-minute limit ({issue}500, {pull}507) by @aladinor
  • MNT: Test on Python 3.12, 3.13 and 3.14 with numpy 2 and require Python >= 3.12 ({issue}487, {pull}488; CI matrix from {pull}484 by @kmuehlbauer) by @aladinor
  • FIX: IRIS SNR-family types (DB_SNR, DB_LOG, DB_CSP, DB_AH, DB_AV, DB_AZDR, 1 and 2 byte) decode as (N - 64) / 2 dB (1 byte, from the IRIS Programming Guide 4.4.37 and checked against reflectivity on the Arouca C-band file in open-radar-data 0.9.0) and (N - 32768) / 100 dB (2 byte) instead of (N - 63) / 2 for both, which gave 2-byte SNR up to about 19900 dB; raw 0 is no data; DB_SNR8 is named SNRH like DB_SNR16, and when two types of a sweep map to one name (e.g. DB_SNR8 + DB_SNR16, or DB_DBZ + DB_DBZ2) the second keeps its Sigmet name instead of replacing the first; SNRH/SNRV have units dB; tests need open-radar-data >= 0.9.0 ({issue}475, {pull}485) by @aladinor
  • FIX: IRIS DB_PHIH/DB_PHIV decode like DB_PHIDP (180 * (N - 1) / 254 degrees, raw 0 no data, IRIS Programming Guide 4.4.24) instead of 180 times the raw word ({issue}474, {pull}483) by @aladinor
  • ENH: Add xarray-native open_datatree with engine= parameter for all 13 backends (odim, cfradial1, cfradial2, nexradlevel2, gamic, iris, furuno, rainbow, datamet, hpl, metek, uf, imd), enabling xd.open_datatree(file, engine="odim") and xr.open_datatree(file, engine="odim"). Legacy open_*_datatree() functions emit FutureWarning and delegate to the new entry points; xd.io.open_imd_datatree([files]) remains the documented exception for multi-file IMD volumes. Also adds public xd.io.list_engines() for engine discovery, NumPy-style docstrings on every BackendEntrypoint.open_groups_as_dict / open_datatree method, and a demo notebook covering all 13 engines. reindex_coord (and the deprecated reindex_angle) is accepted by every engine that reindexes (all but metek and cfradial2), now also applied by cfradial1, and the IMD engine takes site_coords like the other engines (open_imd_datatree accepts both spellings). sweep is resolved by one shared helper on all engines: non-negative integers (numpy included), sweep_N names and /sweep_N paths, alone or mixed in a list; bool, negative, float and other values raise, cfradial1 raises for sweeps missing from the file, and the single-sweep engines (furuno, metek, imd) raise for anything but sweep_0 instead of silently returning it. Previously numpy integers, tuples, sets and ranges silently selected all sweeps on several engines and /sweep_N paths failed; an explicitly selected incomplete NEXRAD sweep is padded as before. The deprecation FutureWarning points at the caller's line ({issue}329, {pull}335) by @aladinor
  • FIX: IRIS DB_SHEAR is read as unsigned (IRIS Programming Guide 4.4.50), so raw 128 is zero shear instead of -51.2 ({issue}476, {pull}489) by @aladinor
  • FIX: HPL reindex_coord angle reindexing failed with first dimension is time because it ran before the angle became the first dimension ({pull}335) by @aladinor
  • FIX: IRIS DB_VELC decodes raw 128 as zero velocity (IRIS Programming Guide 4.4.42) instead of +0.3 m/s, using the DB_VEL scale; raw 254 is +74.4 m/s, not the +75.0 of the guide's table ({issue}477, {pull}491) by @aladinor
  • ENH: to_odim builds what/source from the identifiers the ODIM reader stores in the global attributes (wmo__id, node, site_name, wmo__originating_centre, wmo__wsi) when source is not given, so ODIM files read with xradar can be written back without retyping the source; an explicit source still takes precedence ({issue}98, {pull}441) by @syedhamidali
  • FIX: IRIS 2-byte SQI-format types (DB_SQI2, DB_RHOHV2, DB_RHOH2, DB_RHOV2, DB_PMI16, DB_CCOR16) decode as (N - 1) / 65533 (IRIS Programming Guide 4.4.40), so raw 65534 is 1.0 ({issue}478, {pull}513) by @aladinor
  • FIX: Rainbow reader takes the range start from start_range (the tag used in Rainbow 5 files; startrange was looked up before, so a non-zero start range was ignored), falling back to startrange; range bin centers are computed from the number of bins; Rainbow files can be opened from pathlib.Path ({issue}272, {pull}445) by @syedhamidali
  • FIX: IRIS DB_HVEL2 has a dtype (signed 2 byte, 0.01 m/s, as DB_VVEL2, IRIS Programming Guide 4.4.46; the guide has no DB_HVEL2 section), so files carrying it no longer fail to decode ({issue}479, {pull}514) by @aladinor
  • FIX: NEXRAD Level II reader rewinds file-like objects so every sweep of a datatree can be read (previously all but the first failed), and raises a clear ValueError for gzip-compressed input (asking to decompress it first) and for input that is not a Level II archive, instead of TypeError: NoneType + int ({issue}382, {pull}410) by @syedhamidali
  • FIX: IRIS multi_prf_mode_flag values outside 0-3 warn and use the single-PRF Nyquist velocity instead of scaling velocity by up to 65536 ({issue}480, {pull}517) by @aladinor
  • 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) ({issue}396, {pull}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 ({issue}135, {pull}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 ({issue}407, {pull}411) 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 ({issue}391, {pull}409) 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 ({issue}395, {pull}408) 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 ({issue}412, {pull}414) by @syedhamidali
  • FIX: Fix spacing_is_constant being incorrectly set to false for float32 ranges due to floating-point precision when comparing gate spacing. ({pull}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) ({pull}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 {pull}320, and decode sweep_mode after computing so dask-backed inputs keep the full string ({issue}322) ({pull}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 ({issue}379, {pull}387) 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 ({pull}385) by @chfer
  • 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 ({issue}398, {pull}399) 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 {pull}362) ({issue}366, {pull}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"] ({pull}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 ({issue}376, {pull}377) by @aladinor
  • FIX: ensure to_cfradial2 correctly selects the default storage engine when none is provided, ({pull}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 ({issue}346, {pull}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 ({issue}357, {pull}375) by @aladinor
  • DOC: Add projection comparison and cartopy map examples to Georeference_TargetCRS notebook ({pull}370) by @syedhamidali
  • DOC: Add full-form descriptions for all supported radar formats in README.md ({pull}371) 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 ({issue}368, {pull}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 ({issue}254, {issue}322, {pull}350) 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) ({issue}243, {pull}360) by @syedhamidali
  • FIX: set id-token: write in CI testpypi publisher for trusted publishing ({issue}364) by @aladinor, ({pull}372 ) by @kmuehlbauer
  • MNT: use xarray from PyPI, update pin to xarray=2026.9.0 (last xarray version with Python 3.11) ({pull}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 ({issue}416, {pull}421) 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 ({pull}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 ({pull}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) ({issue}390, {pull}444) by @syedhamidali
  • FIX: Metek reader no longer attaches a units attribute to the already decoded time, which made writing to netCDF fail (as for HPL in {issue}296) ({issue}453, {pull}454) by @syedhamidali
  • ENH: Add xradar.util.is_sweep and .xradar.is_sweep() for Dataset and DataTree to check whether a Dataset (or DataTree node) holds a radar sweep, based on its structure (range and ray dimension, angles, moment variables) instead of the group name, with the ray dimension from the new xradar.util.get_ray_dim (adapted from wradlib.util.dim0); strict=True also requires the mandatory sweep metadata (FM301 Table 301-7a) ({issue}217, {pull}440) 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 ({issue}417, {pull}422) 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 ({issue}418, {pull}423) by @syedhamidali
  • FIX: Halo Photonics .hpl reader: keep the last ray of each sweep (sweeps of one ray were empty and made opening fail, {issue}303), number sweeps from 0, take the header length from the **** separator, raise a ValueError instead of printing on a line-count mismatch, and accept pathlib.Path and binary file-like objects ({issue}430, {pull}442) by @syedhamidali
  • FIX: IRIS reader returns NaN instead of 0.0 for no-data velocity bins (DB_VEL, DB_VELC raw 0, IRIS Programming Guide 4.4.44); the decoder masked them, but the mask was lost in the backend array ({issue}462, {pull}463) by @syedhamidali
  • MNT: IRIS decoders cite the IRIS Programming Guide M212927EN-B (2024); one Nyquist helper for both decode paths, with the dual-PRF factor applied in decode_vel only ({issue}466, {pull}470) by @aladinor
  • FIX: IRIS reader returns NaN for no-data bins (raw 0, IRIS Programming Guide 4.4) of reflectivity, ZDR, PHIDP, WIDTH, RHOHV/SQI, LDR and their variants, instead of real values such as -32 dBZ; IrisRawFile returns masked arrays for them with NaN under the mask, also for DB_VEL/DB_VELC ({issue}465, {pull}467) by @aladinor
  • FIX: IRIS reader fixes UINT1 dtype "unit8"→"uint8" ({issue}462, {pull}493) by @Jah-yee
  • FIX: CfRadial1 export no longer drops rays that share a timestamp; sweeps are concatenated in order along time instead of being aligned on time values, which silently merged such rays (e.g. 7200 → 1080 rays); sweeps with fewer gates are padded with NaN (also in packed moments), moments packed differently per sweep (ODIM) keep their values, attributes that differ between sweeps (UF time units) no longer fail the export, sweep_group_name (in every HPL sweep) is not written as it made the file unreadable, and per-ray variables keep their time dimension ({issue}415, {pull}420) by @syedhamidali
  • FIX: CfRadial2 data can be exported repeatedly, read -> write -> read leaves the datasets unchanged: data read back from a CfRadial2 file no longer fails on export (coordinates and time units in attributes and in the encoding), decoded time units of the UF reader and the boolean global attributes of NEXRAD are written, time_coverage_start/end strings no longer get a time units attribute (the written file could not be read again), and the export writes the names of the sweep groups to sweep_group_name where a reader filled in the sweep numbers ({pull}504) by @syedhamidali
  • FIX: CfRadial1 export of a tree read with optional_groups=True from a CfRadial1 file raised MergeError: unable to determine if these variables should be coordinates (latitude, longitude and altitude inherited into the optional groups); data can be read with the optional groups and exported again any number of times ({pull}505) by @syedhamidali
  • FIX: CfRadial2 reader finds sweeps via the root sweep_group_name (CfRadial 2.1; the sweep_* groups are used if it holds no group names, as written by readers that fill it with the sweep numbers), so files with group names other than sweep_<n> (e.g. Vaisala WindCube Sweep_<id>-<n>) open; sweep_mode is also read from a variable (e.g. Radx), the root sweep_fixed_angle is used as fixed angle, and a file without sweep groups raises a ValueError instead of returning an empty tree ({issue}426, {pull}427) by @syedhamidali
  • ENH: CfRadial1 export writes CfRadial 1.4 metadata per the specification: version = "1.4", Conventions = "Cf/Radial" followed by the sub-conventions actually written (instrument_parameters, radar_parameters, radar_calibration, geometry_correction), and meta_group attributes on their variables; previously Cf/Radial / 1.2 was written although the content already used 1.3+ naming ({issue}388, {pull}425) by @syedhamidali
  • FIX: ODIM TH/TV (logged total power in dBZ, ODIM_H5 2.4 Table 16) are now read as DBTH/DBTV as in FM301 (Table 301-9), where TH/TV denote the linear quantities; they were labelled as linear and unitless before. to_odim writes DBTH/DBTV as TH/TV. Note: code accessing ds.TH of ODIM data needs to use ds.DBTH ({issue}109, {pull}443) by @syedhamidali
  • FIX: reading the CfRadial1 calibration group no longer fails with StopIteration on non-standard variable names or when names contain each other (_h/_v); calibration names are matched exactly, and names the reader keeps as they are are written back unchanged by to_cfradial1 instead of getting an r_calib_ prefix. The export writes the names of the CfRadial 1.4 tables (e.g. radar_receiver_bandwidth, r_calib_base_1km_hc), the reader accepts these and the aliases of other software ({issue}419, {pull}424) by @syedhamidali
  • FIX: CfRadial1 export of sweeps with different range geometry (e.g. GAMIC 100 m / 150 m gates) raises a clear error (MergeError, a ValueError) that points to reindex_range and says that it takes the nearest gate (CfRadial 1.4 section 2.5), NEXRAD split cuts (same elevation, different moments) are covered by a test ({issue}418, {pull}455) by @syedhamidali
  • ENH: Implement guess_can_open for all backends (format signatures and the input types each backend reads) and add xradar.io.discover_engine / xradar.io.list_xradar_engines; formats unknown to xarray (NEXRAD Level II, IRIS, Rainbow, UF, ...) can now be opened with xr.open_dataset without engine ({issue}225, {issue}380, {pull}446) by @syedhamidali
  • DOC: Name_Mapping notebook with tables of how the readers and exporters map the names of moments and metadata (built from the mappings of the code), linked from the importers page ({issue}46, {pull}523) by @syedhamidali
  • ENH: xd.open_datatree finds the engine with xd.io.discover_engine when engine is not given, which also works for netCDF/HDF5 based formats (ODIM_H5, GAMIC, CfRadial, IMD) that xr.open_datatree without engine hands to xarray's netCDF backends, and stacks a list of files with one sweep each into a volume (xradar.util.create_volume); CfRadial2 backend implements guess_can_open; the Open-Datatree-Engine and Open-Any-Format notebooks show both ({issue}225, {issue}380, {pull}446) by @syedhamidali
  • DOC: links to the standards (WMO FM301, CfRadial, ODIM_H5) in the Name_Mapping notebook ({pull}523) by @syedhamidali
  • FIX: the radar_calibration group of volumes whose sweeps carry different calibration attributes no longer raises KeyError: each value is taken from the first selected sweep which has it. Values the sweeps disagree about (e.g. the noise level of each cut) are left out of the group, so that no value which holds for only a part of the volume is written, and a warning lists them (select the wanted sweep with sweep=). Shared helpers to fill radar_parameters and radar_calibration from sweep attributes ({issue}232, {pull}532) 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 ({issue}341) by @kmuehlbauer, ({pull}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 ({issue}361, {pull}362) by @aladinor
  • ADD: open_cfradial2_datatree reader with grouped CfRadial2 compatibility normalization for common FM301/CfRadial2 naming differences ({issue}93, {issue}287), ({pull}349) by @syedhamidali
  • ENH: Move station coordinates (latitude, longitude, altitude) to root node as coordinates for DataTree coordinate inheritance ({issue}331, {pull}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 ({issue}331, {pull}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 ({issue}334, {pull}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 ({pull}332) by @aladinor
  • ADD: incomplete_sweep parameter ("drop"/"pad") to open_nexradlevel2_datatree for handling incomplete sweeps in partial volume data ({pull}332) by @aladinor
  • ADD: Notebook example for streaming NEXRAD Level 2 chunks from S3 (nexrad_read_chunks.ipynb) ({pull}332) by @aladinor
  • ADD: Comprehensive test suite for chunk list-input and incomplete sweep handling ({pull}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 ({issue}338, {pull}339) by @aladinor
  • FIX: Set indexes and wrap variables in CopyOnWriteArray for ODIM and GAMIC backends, fixes pickle error for BufferedReader ({issue}189) by @Ockenfuss, ({pull}345) by @kmuehlbauer
  • FIX: Allow passing inherit parameter to apply_to_sweeps / map_over_sweeps to control coordinate inheritance from root node ({issue}343, {pull}344) by @aladinor
  • FIX: Use open-radar-data fixture as fallback for nexrad_read_chunks.ipynb notebook, replacing dependency on ephemeral S3 chunk data ({issue}351, {pull}352) by @aladinor
  • MNT: Pin open-radar-data>=0.6.0 for NEXRAD chunk test data ({pull}352) by @aladinor
  • MNT: Transform ipynb notebooks to myst markdown notebooks ({issue}342, {pull}348) by @kmuehlbauer
  • DOC: Link WMO Manual on Codes in README.md ({issue}308, {pull}353 ) @kmuehlbauer

0.11.1 (2026-02-03)

  • MNT: Pre-commit update + lint ({pull}325) by @kmuehlbauer
  • FIX: Use dtype with fallback in odim export ({pull}324) by @katelbach
  • FIX: Prevent azimuth-folding for RHI for gamic reader ({pull}326) by @kmuehlbauer

0.11.0 (2026-01-12)

  • ENH: get radar coordinates with given reference system ({issue}243) ({pull}300) by @egouden
  • ENH: Disable fill value in rainbow reader ({issue}103) ({pull}290) by @egouden
  • ADD: read nyquist_velocity in ODIM and GAMIC HDF5 files ({pull}291) by @katelbach
  • MNT: update and harden CI, add zizmor to precommit, add dependabot ({pull}294) by @kmuehlbauer
  • FIX: Return float32 for float types (keep other dtypes) and remove erroneous "units" from time attrs for hpl reader. ({issue}296) ({pull}297) by @kmuehlbauer
  • MNT: Fix Windows errors in file handling ({pull}295) by @egouden
  • MNT: do not overwrite Dataset for Dataset.update ({pull}302) by @kmuehlbauer
  • FIX: Properly handle zero and NaN values during IRIS/Sigmet KDP decode. ({pull}301) by @billvieux
  • FIX: NEXRAD Level2 backend compatibility with older files and VCP-0 ({issue}311, {pull}312) by @aladinor
  • FIX: Add explicit compat="no_conflicts", to xr.merge() in _get_subgroup to silence xarray FutureWarning ({issue}313, {pull}314) by @aladinor.
  • MNT: create individual notebook tests with pytest_generate_tests and use tmp_path-fixture ({pull}316) by @kmuehlbauer
  • FIX: Ensure backend closers are available ({pull}318) by @kmuehlbauer
  • MNT: Enhance contributing experience ({pull}315) by @egouden
  • ENH: Add combine_sweeps function to stack sweeps into a single radar volume with optional time and angle filtering ({pull}307) by @egouden
  • FIX: Use time-dimension to stack/unstack CfRadial1 data for variable number of gates, properly handle duplicates ({issue}317), ({pull}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. ({issue}265) ({pull}280) by @aladinor
  • ADD: function to select dataset variables in sweep ({issue}104) ({pull}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". ({issue}253) ({pull}274) by @Steve-Roderick.
  • FIX: Prevent literal timedelta decoding for new xarray versions, fix tests, update pinnings ({pull}278) by @kmuehlbauer.
  • MNT: Package and Documentation cleanup ({issue}273), {pull}284) by @kmuehlbauer.
  • ADD: Support Universal Format (UF) ({issue}275) ({pull}276) by @kmuehlbauer.
  • ADD: NDPointIndex Notebook example ({pull}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 ({pull}238) by @aladinor
  • FIX: Improving performance of open_nexradlevel2_datatree function and adding tests for sweep parameter. ({issue}239) ({pull}240) by @aladinor
  • FIX: Keeping attributes at each variable when using open_nexradlevel2_datatree. ({issue}241) ({pull}242) by @aladinor
  • FIX: Correctly read transition rays in RHI scans ({issue}247) ({pull}250) by @rcjackson
  • FIX: Correctly open NEXRAD files when split cut mode is enable ({issue} 245) ({pull}246) by @aladinor
  • ADD: Example Notebook for assigning geocoords. ({issue}243) and ({pull}251) by @syedhamidali
  • FIX: DataTree reader now works with sweeps containing different variables ({pull}252) by @egouden.
  • FIX: Correct retrieval of intermediate records in nexrad level2 reader ({issue}259) ({pull}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 ({issue}264) ({pull}266) by @kmuehlbauer.
  • ENH: Add message type 1 decoding to nexrad level 2 reader ({issue}256) ({pull}267) by @kmuehlbauer.
  • ENH: Introduce file locks for nexrad level2 and iris backend ({issue}207) ({pull}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 ({issue}233) by @syedhamidali, ({pull}234) by @kmuehlbauer.
  • FIX: Correctly handle 8bit/16bit, big-endian/little-endian in nexrad reader (PHI and ZDR) ({issue}230) by @syedhamidali, ({pull}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 ({pull}221) by @aladinor
  • ENH: Added pytests to the missing functions in the test_xradar and test_iris in order to increase codecov in ({pull}228) by @syedhamidali.
  • ENH: Updated Readme ({pull}226) by @syedhamidali.
  • ADD: Added new module transform for transforming CF1 data to CF2 and vice versa ({pull}224) by @syedhamidali.
  • Use DataTree from xarray and add xarray nightly run ({pull}213, {pull}214, {pull}215, {pull}218) by @kmuehlbauer.
  • ADD: Added new accessor map_over_sweeps for volume operations on DataTrees and a matching decorator ({pull}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, ({pull}202).
  • ADD: Metek Micro Rain Radar 2 reader by @rcjackson, ({pull}200) by @rcjackson.

0.6.5 (2024-09-20)

  • FIX: Azimuth dimension now labelled correctly for Halo Photonics data ({pull}206) by @rcjackson.
  • FIX: do not apply scale/offset in datamet reader, leave it to xarray instead ({pull}209) by @kmuehlbauer.

0.6.4 (2024-08-30)

  • FIX: Notebooks are now conforming to ruff's style checks by @rcjackson, ({pull}199) by @rcjackson.
  • FIX: use dict.get() to retrieve attribute key and return "None" if not available, ({pull}200) by @kmuehlbauer

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 ({issue}194) by @aladinor, ({pull}195) by @aladinor

0.6.1 (2024-08-07)

0.6.0 (2024-08-05)

  • ADD: DataMet reader ({pull}175) by @wolfidan.
  • FIX: Nexrad level2 time offset of 1 day, skip reading missing elevations, introduce new radial_status of 5 ({issue}180) by @ghiggi, ({pull}180) by @kmuehlbauer.
  • ADD: Reader for Halo Photonics Doppler lidar data by @rcjackson

0.5.1 (2024-07-05)

  • ADD: Add Alfonso to citation doc ({pull}169) by @mgrover1.
  • ENH: Adding global variables and attributes to iris datatree ({pull}166) by @aladinor.
  • FIX: Set fillvalue before applying scale/offset when exporting to odim ({issue}122) by @pavlikp, ({pull}173) by @kmuehlbauer.
  • FIX: Fix use of ruff, CI and numpy2 ({pull}177) by @mgrover1 and @kmuehlbauer.

0.5.0 (2024-03-28)

  • MNT: Update GitHub actions, address DeprecationWarnings ({pull}153) by @kmuehlbauer.
  • MNT: restructure odim.py/gamic.py, add test_odim.py/test_gamic.py ({pull}154) by @kmuehlbauer.
  • MNT: use CODECOV token ({pull}155) by @kmuehlbauer.
  • MNT: fix path for notebook coverage ({pull}157) by @kmuehlbauer.
  • ADD: NEXRAD Level2 structured reader ({pull}158) by @kmuehlbauer and @mgrover1.
  • FIX: Add the proper elevation angle to fixed angle ({pull}162) by @mgrover1.
  • ENH: Add a utility for finding sweep number keys ({pull}167) by @mgrover1.

0.4.3 (2024-02-24)

  • MNT: address black style changes, update pre-commit-config.yaml ({pull}152) by @kmuehlbauer.
  • FIX: use len(unique) to estimate unique entry for odim range ({pull}151) by @martinpaule.

0.4.2 (2023-11-02)

  • FIX: Fix handling of sweep_mode attributes ({pull}143) by @mgrover1
  • FIX: explicitely check for "False" in get_crs() {pull}142) by @kmuehlbauer.

0.4.1 (2023-10-26)

  • FIX: Add history to cfradial1 output, and fix minor error in CfRadial1_Export.ipynb notebook({pull}132) by @syedhamidali
  • FIX: fix readthedocs build for python 3.12 ({pull}140) by @kmuehlbauer.
  • FIX: align coordinates in backends, pin python >3.9,<=3.12 in environment.yml ({pull}139) by @kmuehlbauer
  • FIX: prevent integer overflow when calculating azimuth in FURUNO scn files ({issue}137) by @giacant , ({pull}138) by @kmuehlbauer

0.4.0 (2023-09-27)

  • ENH: Add cfradial1 exporter ({issue}124) by @syedhamidali, ({pull}126) by @syedhamidali
  • FIX: use datastore._group instead of variable["sweep_number"] ({issue}121) by @aladinor , ({pull}123) by @kmuehlbauer
  • MIN: use "crs_wkt" instead of deprecated "spatial_ref" when adding CRS ({pull}127) by @kmuehlbauer
  • FIX: always read nodata and undetect attributes from ODIM file ({pull}125) by @egouden
  • MIN: use cmweather colormaps in xradar ({pull}128) by @kmuehlbauer.

0.3.0 (2023-07-11)

  • ENH: Add new examples using radar data on AWS s3 bucket ({pull}102) by @aladinor
  • FIX: Correct DB_DBTE8/DB_DBZE8 and DB_DBTE16/DB_DBZE16 decoding for iris-backend ({pull}110) by @kmuehlbauer
  • FIX: Cast boolean string to int in rainbow dictionary ({pull}113) by @egouden
  • MNT: switch to mamba-org/setup-micromamba, split CI tests ({issue}115), ({pull}116) by @kmuehlbauer
  • FIX: time interpolation ({pull}117) by @kmuehlbauer
  • FIX: robust angle_res retrieval in extract_angle_parameters ({issue}112), ({pull}118) by @kmuehlbauer
  • FIX: robust radar identifier in to_odim() ({pull}120) by @kmuehlbauer

0.2.0 (2023-03-24)

  • ENH: switch to add optional how attributes in ODIM format writer ({pull}97) by @egouden
  • FIX: add keyword argument for mandatory source attribute in ODIM format writer ({pull}96) by @egouden
  • FIX: check for dim0 if not given, only swap_dims if needed ({issue}92), ({pull}94) by @kmuehlbauer
  • FIX+ENH: need array copy before overwriting and make compression available in to_odim ({pull}95) by @kmuehlbauer

0.1.0 (2023-02-23)

  • Add an example on reading multiple sweeps into a single object ({pull}69) by @mgrover1
  • ENH: add spatial_ref with pyproj when georeferencing, add/adapt methods/tests ({issue}38), ({pull}87) by @kmuehlbauer
  • Docs/docstring updates, PULL_REQUEST_TEMPLATE.md ({pull}89) by @kmuehlbauer
  • Finalize release 0.1.0, add testpypi upload on push to main ({pull}91) by @kmuehlbauer

0.0.13 (2023-02-09)

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

0.0.12 (2023-02-09)

  • ENH: add IRIS DB_VELC decoding and tests ({issue}78), ({pull}83) by @kmuehlbauer
  • FIX: furuno backend inconsistencies ({issue}77), ({pull}82) by @kmuehlbauer
  • FIX: ODIM_H5 backend inconsistencies ({issue}80), ({pull}81) by @kmuehlbauer

0.0.11 (2023-02-06)

  • fix _Undetect/_FillValue in odim writer ({pull}71) by @kmuehlbauer
  • port more backend tests from wradlib ({pull}73) by @kmuehlbauer

0.0.10 (2023-02-01)

  • add WRN110 scn format to Furuno reader ({pull}65) by @kmuehlbauer
  • Adapt to new build process, pyproject.toml only, use ruff for linting ({pull}67) by @kmuehlbauer

0.0.9 (2022-12-11)

  • add ODIM_H5 exporter ({pull}39) by @kmuehlbauer
  • fetch radar data from open-radar-data ({pull}44) by @kmuehlbauer
  • align readers with CfRadial2, add CfRadial2 exporter ({pull}45), ({pull}49), ({pull}53), ({pull}56), ({pull}57) and ({pull}58) by @kmuehlbauer
  • add georeference accessor, update examples ({pull}60), ({pull}61) by @mgrover1
  • refactored and partly reimplemented angle reindexing ({issue}55), ({pull}62) by @kmuehlbauer

0.0.8 (2022-09-28)

0.0.7 (2022-09-21)

  • Add zenodo badges to README.md ({pull}22) by @mgrover1
  • Fix version on RTD ({pull}23) by @kmuehlbauer
  • Add minimal documentation for Datamodel ({pull}24) by @kmuehlbauer

0.0.6 (2022-09-19)

  • Improve installation and contribution guide, update README.md with more badges, add version and date of release to docs, update install process ({pull}19) by @kmuehlbauer
  • Add minimal documentation for CfRadial1 and ODIM_H5 importers ({pull}20) by @kmuehlbauer
  • Add accessors.py submodule, add accessors showcase ({pull}21) by @kmuehlbauer

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.

Metadata

Release files for xradar 0.13.0

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

Source distribution (sdist)

Source distribution for xradar 0.13.0
File Size Uploaded Provenance Actions
xradar-0.13.0.tar.gz 391.5 kB Without provenance Details for xradar-0.13.0.tar.gz

Built distribution (wheel)

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

Total release size: 602.9 kB

Release files / xradar-0.13.0.tar.gz

Download URL xradar-0.13.0.tar.gz
Size 391.5 kB
Tags Source
SHA-256 checksum
How to use checksums
3bb0f4b433702b0abf55f81aeb125bffc6769062794c0896850e9ddf59800b1e
BLAKE2b-256 checksum
How to use checksums
850aca208ade2ed89174ccb3ed9f612f4707ef9b3b4831126b10404c160e0521
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / xradar-0.13.0-py3-none-any.whl

Download URL xradar-0.13.0-py3-none-any.whl
Size 211.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
485cfb65b391651d42a765333fd2cc506e7f113d6b2d67b5bd0f252b4575e720
BLAKE2b-256 checksum
How to use checksums
090a7a43dc80ed684a0b3978f3783cc67426ebc66546131ff4c6d52bf336ae3d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for xradar 0.13.0

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.13.0 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