xradar
Xradar includes all the tools to get your weather radar into the xarray data model.
- Code: MIT license
- Documentation: CC-BY-SA-4.0 https://docs.openradarscience.org/projects/xradar
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
- CfRadial1 and CfRadial2 — CF/Radial convention for radar data
- ODIM_H5 — EUMETNET OPERA Data Information Model (HDF5)
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!
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()andDataTree.close()release the file for every backend, also aftergeoreference()/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 acceptpathlib.Path(as HPL and Rainbow do), UF reads datatrees from file-like objects (sweep discovery consumed the object without rewinding), and the CfRadial1 backend appliesfix_second_angleto sweep groups inopen_datasetandopen_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_*_datatreefunctions andxd.open_datatreego throughxr.open_datatreeagain, sochunks,cacheandbackend_kwargswork as before {pull}335, legacyoptional=Falseno longer raises, and iris, rainbow, furuno and datamet sweeps keep theirrangeindex;optional_groups=Trueno longer copieslatitude/longitude/altitudeinto/radar_parametersand/georeferencing_correction; thereindex_angleFutureWarning is emitted once and points at the caller;open_uf_datatreehas its signature and docstring back; the CfRadial1 and CfRadial2 backend option for the netCDF reader isnetcdf_engine(enginestill works inopen_cfradial1_datatreeandopen_cfradial2_datatree), sinceenginecollided with xarray's own argument; as inxr.open_datatree, a keyword given both directly and inbackend_kwargstakes thebackend_kwargsvalue, and passing bothsite_coordsandsite_as_coordsraisesTypeError; NEXRAD and UF sweeps get arangeindex like the other engines, and both honourfirst_dimgiven inbackend_kwargs; the CfRadial2 backend stays lazy andclose()releases the file ({issue}481, {pull}484) by @aladinor and @kmuehlbauer - DOC:
multiple-sweeps-into-volume-scannotebook 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}484by @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) / 2dB (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) / 100dB (2 byte) instead of(N - 63) / 2for both, which gave 2-byte SNR up to about 19900 dB; raw 0 is no data;DB_SNR8is namedSNRHlikeDB_SNR16, and when two types of a sweep map to one name (e.g.DB_SNR8+DB_SNR16, orDB_DBZ+DB_DBZ2) the second keeps its Sigmet name instead of replacing the first;SNRH/SNRVhave unitsdB; tests need open-radar-data >= 0.9.0 ({issue}475, {pull}485) by @aladinor - FIX: IRIS
DB_PHIH/DB_PHIVdecode likeDB_PHIDP(180 * (N - 1) / 254degrees, 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_datatreewithengine=parameter for all 13 backends (odim, cfradial1, cfradial2, nexradlevel2, gamic, iris, furuno, rainbow, datamet, hpl, metek, uf, imd), enablingxd.open_datatree(file, engine="odim")andxr.open_datatree(file, engine="odim"). Legacyopen_*_datatree()functions emitFutureWarningand delegate to the new entry points;xd.io.open_imd_datatree([files])remains the documented exception for multi-file IMD volumes. Also adds publicxd.io.list_engines()for engine discovery, NumPy-style docstrings on everyBackendEntrypoint.open_groups_as_dict/open_datatreemethod, and a demo notebook covering all 13 engines.reindex_coord(and the deprecatedreindex_angle) is accepted by every engine that reindexes (all butmetekandcfradial2), now also applied bycfradial1, and the IMD engine takessite_coordslike the other engines (open_imd_datatreeaccepts both spellings).sweepis resolved by one shared helper on all engines: non-negative integers (numpy included),sweep_Nnames and/sweep_Npaths, alone or mixed in a list;bool, negative, float and other values raise,cfradial1raises for sweeps missing from the file, and the single-sweep engines (furuno,metek,imd) raise for anything butsweep_0instead of silently returning it. Previously numpy integers, tuples, sets and ranges silently selected all sweeps on several engines and/sweep_Npaths failed; an explicitly selected incomplete NEXRAD sweep is padded as before. The deprecationFutureWarningpoints at the caller's line ({issue}329, {pull}335) by @aladinor - FIX: IRIS
DB_SHEARis 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_coordangle reindexing failed withfirst dimension is timebecause it ran before the angle became the first dimension ({pull}335) by @aladinor - FIX: IRIS
DB_VELCdecodes raw 128 as zero velocity (IRIS Programming Guide 4.4.42) instead of +0.3 m/s, using theDB_VELscale; raw 254 is +74.4 m/s, not the +75.0 of the guide's table ({issue}477, {pull}491) by @aladinor - ENH:
to_odimbuildswhat/sourcefrom the identifiers the ODIM reader stores in the global attributes (wmo__id,node,site_name,wmo__originating_centre,wmo__wsi) whensourceis not given, so ODIM files read with xradar can be written back without retyping the source; an explicitsourcestill 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;startrangewas looked up before, so a non-zero start range was ignored), falling back tostartrange; range bin centers are computed from the number of bins; Rainbow files can be opened frompathlib.Path({issue}272, {pull}445) by @syedhamidali - FIX: IRIS
DB_HVEL2has a dtype (signed 2 byte, 0.01 m/s, asDB_VVEL2, IRIS Programming Guide 4.4.46; the guide has noDB_HVEL2section), 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
ValueErrorfor gzip-compressed input (asking to decompress it first) and for input that is not a Level II archive, instead ofTypeError: NoneType + int({issue}382, {pull}410) by @syedhamidali - FIX: IRIS
multi_prf_mode_flagvalues 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_31azimuth_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
Griddingnotebook showing how to grid xradar volumes into 3D Cartesian grids with Py-ART (grid_from_radars) and wradlib (vpr.CAPPIand sweep-wise.wrl.ipol.interpolatewith 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_coordbackend kwarg replacingreindex_angle: a nested dictreindex_coord=dict(angle=dict(...), range=dict(...))reindexes angle (duplicates removed,util.reindex_angle,util.ipol_time) and/or range (newutil.reindex_range, analogous toreindex_angle) for all backends and datatree openers (HPL newly supported).reindex_anglestill works but emits aFutureWarning; non-dict values now raise a clear error. TheMulti-Volume-Concatenationnotebook uses it to align the slightly differing ranges of its volumes ({issue}407, {pull}411) by @syedhamidali - FIX: IRIS
site_coordsfolded southern-hemisphere latitudes (BIN4 > 180°) with the longitude, solatitudecame out aslongitude - 360; fold the latitude itself ({issue}391, {pull}409) by @syedhamidali - FIX: ODIM reader no longer fails on quality groups carrying a compound-dtype
legendtable (ODIM_H5 2.4, e.g. the FMI open archive since 2026-06); the table is attached to the group's classification variable as CFflag_values/flag_meanings(ODIM 2.3/2.4 Section 6.2key/valueand FMIcode/classlayouts) instead of being merged as ray data, and awhat/legendstring attribute is kept aslegend({issue}395, {pull}408) by @syedhamidali - FIX:
open_odim_datatree,open_rainbow_datatree,open_hpl_datatreeandopen_metek_datatreemapped 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 andsweep_Nnames, 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-Concatenationnotebook for xarray 2026.9 — determine the rotation direction from the time-ordered azimuth differences instead ofdiff("time")on a sweep whose dimension isazimuth(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_gatesand shorter rays are padded with NaN, instead of assuming the first ray's gate count for the whole sweep. Also restore RHI detection (elevationas first dimension), which broke in {pull}320, and decodesweep_modeafter 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 thecalibsbool/variable name collision, robusthistoryattribute and missing-elevationhandling, and a shared_build_cfradial1_datasetreused byxradar.transform.to_cfradial1to 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>=3soDataTree.to_zarr()works with current xarray (which forwards azarr_formatargument thatzarr<3'sopen_group()rejects), and fill masked moments (e.g. IRISVRADH) in themultiple-sweeps-into-volume-scannotebook before writing, since zarr v3 codecs cannot serialize numpyMaskedArray({issue}398, {pull}399) by @syedhamidali - FIX:
open_nexradlevel2_datatreedecodes volumes with interior sweep-index gaps end-to-end — translate sweep label → compact position inNexradLevel2Store.open_store_coordinatesso the per-sweep entrypoint stops positionally indexing the compactedmsg_31_header(follow-up to {pull}362) ({issue}366, {pull}374) by @aladinor - DOC:
nexrad_read_chunksnotebook now falls back to the open-radar-data fixture when the live S3 listing yields no complete sweep. The guard only caughtValueError, but a listing holding just the start (S) chunk parses fine and returns aDataTreewith no sweep groups, so the fallback was skipped and the notebook failed ondtree["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_recordhard-coded a 120-message stride; per ICD2620010J§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 forget_data's per-moment replay ({issue}376, {pull}377) by @aladinor - FIX: ensure
to_cfradial2correctly selects the default storage engine when none is provided, ({pull}378) by @chfer - MNT: Add
cfradial1_sgp_filesession fixture and refactor 8 tests intest_util.py/test_accessors.pyto share it instead of inliningDATASETS.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_datainitialisedj = -1so the first matching ray of the first-loaded moment was written toraw_data[-1]; affects files withoutDB_XHDR(data-type bit 0) whereDB_DBTbecomes the rotated moment ({issue}357, {pull}375) by @aladinor - DOC: Add projection comparison and cartopy map examples to
Georeference_TargetCRSnotebook ({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_datatreeaccepts 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_cfradial2to reopen root-onlyengine="cfradial1"datasets, and normalize sweep metadata aftermap_over_sweepsoperations so filtered volumes can be exported to CfRadial1 again ({issue}254, {issue}322, {pull}350) by @syedhamidali - ENH: Expose
target_crson.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: writein 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 setsn_gates_varytofalse); 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,versionandhistoryare now set on the exported root), and preserve the input DataTree by working on a copy, which is shallow by default; usedeepcopy=Truefor a deep copy ({pull}384) by @chfer - DOC: Fix the roundtrip example in
CfRadial1_Model_Transformation.mdby settingfirst_dim="time"andoptional=Falsewhen creatingdtree3, 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 oneuint8value per range bin; they were returned as packedint16words holding two bins each.DB_HCLASS/DB_HCLASS2get CFflag_masks/flag_values/flag_meaningsfor the HydroClass bit segments, from the classifiers stored intask_end_info(IRIS Programming Guide 4.4.14) ({issue}390, {pull}444) by @syedhamidali - FIX: Metek reader no longer attaches a
unitsattribute to the already decodedtime, which made writing to netCDF fail (as for HPL in {issue}296) ({issue}453, {pull}454) by @syedhamidali - ENH: Add
xradar.util.is_sweepand.xradar.is_sweep()for Dataset and DataTree to check whether a Dataset (or DataTree node) holds a radar sweep, based on its structure (rangeand ray dimension, angles, moment variables) instead of the group name, with the ray dimension from the newxradar.util.get_ray_dim(adapted fromwradlib.util.dim0);strict=Truealso 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
.hplreader: 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 aValueErrorinstead of printing on a line-count mismatch, and acceptpathlib.Pathand binary file-like objects ({issue}430, {pull}442) by @syedhamidali - FIX: IRIS reader returns NaN instead of
0.0for no-data velocity bins (DB_VEL,DB_VELCraw0, 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_velonly ({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;IrisRawFilereturns masked arrays for them with NaN under the mask, also forDB_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
timeinstead 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 theirtimedimension ({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 (
coordinatesand timeunitsin attributes and in the encoding), decoded timeunitsof the UF reader and the boolean global attributes of NEXRAD are written,time_coverage_start/endstrings no longer get a timeunitsattribute (the written file could not be read again), and the export writes the names of the sweep groups tosweep_group_namewhere a reader filled in the sweep numbers ({pull}504) by @syedhamidali - FIX: CfRadial1 export of a tree read with
optional_groups=Truefrom a CfRadial1 file raisedMergeError: 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; thesweep_*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 thansweep_<n>(e.g. Vaisala WindCubeSweep_<id>-<n>) open;sweep_modeis also read from a variable (e.g. Radx), the rootsweep_fixed_angleis used as fixed angle, and a file without sweep groups raises aValueErrorinstead 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), andmeta_groupattributes on their variables; previouslyCf/Radial/1.2was 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 asDBTH/DBTVas in FM301 (Table 301-9), whereTH/TVdenote the linear quantities; they were labelled as linear and unitless before.to_odimwritesDBTH/DBTVasTH/TV. Note: code accessingds.THof ODIM data needs to useds.DBTH({issue}109, {pull}443) by @syedhamidali - FIX: reading the CfRadial1 calibration group no longer fails with
StopIterationon 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 byto_cfradial1instead of getting anr_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, aValueError) that points toreindex_rangeand 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_openfor all backends (format signatures and the input types each backend reads) and addxradar.io.discover_engine/xradar.io.list_xradar_engines; formats unknown to xarray (NEXRAD Level II, IRIS, Rainbow, UF, ...) can now be opened withxr.open_datasetwithoutengine({issue}225, {issue}380, {pull}446) by @syedhamidali - DOC:
Name_Mappingnotebook 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_datatreefinds the engine withxd.io.discover_enginewhenengineis not given, which also works for netCDF/HDF5 based formats (ODIM_H5, GAMIC, CfRadial, IMD) thatxr.open_datatreewithoutenginehands to xarray's netCDF backends, and stacks a list of files with one sweep each into a volume (xradar.util.create_volume); CfRadial2 backend implementsguess_can_open; theOpen-Datatree-EngineandOpen-Any-Formatnotebooks show both ({issue}225, {issue}380, {pull}446) by @syedhamidali - DOC: links to the standards (WMO FM301, CfRadial, ODIM_H5) in the
Name_Mappingnotebook ({pull}523) by @syedhamidali - FIX: the
radar_calibrationgroup of volumes whose sweeps carry different calibration attributes no longer raisesKeyError: 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 withsweep=). Shared helpers to fillradar_parametersandradar_calibrationfrom sweep attributes ({issue}232, {pull}532) by @syedhamidali
0.12.0 (2026-04-21)
- MNT: Unpin xarray, require
xarray >= 2026.4.0inrequirements.txt,environment.yml,ci/unittests.yml, andci/notebooktests.ymlby @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_datatreekeeps sweeps with interior sweep-index gaps — derive sweep names from actual indices innex.datainstead ofrange(len(...))so upstream-dropped interior cuts (e.g.[0..9, 11]) no longer raiseKeyError({issue}361, {pull}362) by @aladinor - ADD:
open_cfradial2_datatreereader 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_groupsparameter (defaultFalse) to allopen_*_datatree()functions to control inclusion of/radar_parameters,/georeferencing_correction, and/radar_calibrationsubgroups ({issue}331, {pull}333) by @aladinor - ENH: Skip redundant station coordinate reads for subsequent sweeps in DataTree by passing
site_as_coords=Falseand extracting shared_apply_site_as_coordshelper ({issue}334, {pull}337) by @aladinor - ADD: Support list/tuple of chunk files (bytes, file-like, or paths) as input to
open_nexradlevel2_datatreefor streaming NEXRAD Level 2 data from S3 chunk buckets ({pull}332) by @aladinor - ADD:
incomplete_sweepparameter ("drop"/"pad") toopen_nexradlevel2_datatreefor 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
inheritparameter toapply_to_sweeps/map_over_sweepsto control coordinate inheritance from root node ({issue}343, {pull}344) by @aladinor - FIX: Use
open-radar-datafixture as fallback fornexrad_read_chunks.ipynbnotebook, replacing dependency on ephemeral S3 chunk data ({issue}351, {pull}352) by @aladinor - MNT: Pin
open-radar-data>=0.6.0for 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
dtypewith 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",toxr.merge()in_get_subgroupto 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_sweepsfunction 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_datatreefunction for all backends. Adding "scan_name" to nexradlevel2 datatree attributes ({pull}238) by @aladinor - FIX: Improving performance of
open_nexradlevel2_datatreefunction and adding tests forsweepparameter. ({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_dictdatatree constructor. Test for_get_required_root,_get_subgroup, and_get_radar_calibrationwere also added ({pull}221) by @aladinor - ENH: Added pytests to the missing functions in the
test_xradarandtest_irisin order to increase codecov in ({pull}228) by @syedhamidali. - ENH: Updated Readme ({pull}
226) by @syedhamidali. - ADD: Added new module
transformfor 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_sweepsfor 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_sweepsfunction for applying custom operations to all sweeps in aDataTreeradar 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)
- FIX: use rstart in meter for ODIM_H5/V2_4 ({issue}
196) by @kmuehlbauer, ({pull}197) by @kmuehlbauer.
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)
- MNT: minimize CI ({pull}
192) by @kmuehlbauer. - FIX: properly read CfRadial1 n_points files ({issue}
188) by @aladinor, ({pull}190) by @kmuehlbauer.
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
cmweathercolormaps 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_resretrieval inextract_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_VELCdecoding 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/_FillValuein 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
rufffor 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)
- add GAMIC HDF5 importer ({pull}
29) by @kmuehlbauer - add Furuno SCN/SCNX importer ({pull}
30) by @kmuehlbauer - add Rainbow5 importer ({pull}
32) by @kmuehlbauer - add Iris/Sigmet importer ({pull}
33) by @kmuehlbauer - add georeferencing (AEQD) ({pull}
28) by @mgrover1
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)
- Data Model, CfRadial1 Backend ({pull}
13) by @kmuehlbauer - ODIM_H5 Backend ({pull}
14) by @kmuehlbauer
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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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.