.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/retrieve/plot_qpe.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_retrieve_plot_qpe.py: ======================================================= Radar-Based Quantitative Precipitation Estimation (QPE) ======================================================= This script processes radar data to compute vertical column profiles at a specific point location and estimate rain rates using categorized reflectivity. The rain rates are then saved as a NetCDF file. - The `column_profile` function extracts a vertical profile at a given latitude/longitude. - The `rain_rate_categorized` function computes rain rates based on categorized reflectivity. - The script reads multiple radar files, processes them, and visualizes the results. **Note:** If you want to increase the area considered for the vertical profile, you can increase `azimuth_spread` and `spatial_spread`. Each increment corresponds to the radar's azimuth resolution and range resolution, respectively. .. GENERATED FROM PYTHON SOURCE LINES 17-180 .. rst-class:: sphx-glr-horizontal * .. image-sg:: /examples/retrieve/images/sphx_glr_plot_qpe_001.png :alt: QPE :srcset: /examples/retrieve/images/sphx_glr_plot_qpe_001.png :class: sphx-glr-multi-img * .. image-sg:: /examples/retrieve/images/sphx_glr_plot_qpe_002.png :alt: QPE :srcset: /examples/retrieve/images/sphx_glr_plot_qpe_002.png :class: sphx-glr-multi-img .. code-block:: Python print(__doc__) # Author: Hamid Ali Syed (syed@rixvi.com) # License: BSD 3-Clause import logging from datetime import datetime import fsspec import matplotlib.pyplot as plt import numpy as np import pytz import xarray as xr import pyart def column_profile( radar: pyart.core.Radar, latitude: float = 33.8, longitude: float = -88.3, azimuth_spread: float = 3, spatial_spread: float = 3, v_res: float = 100, min_alt: float = None, max_alt: float = None, ) -> xr.Dataset: """ Extracts a vertical column profile from radar data and interpolates it onto a uniform height grid. **Expanding the Area:** - Increase `azimuth_spread` to expand the azimuthal range. - Increase `spatial_spread` to include more horizontal coverage. Parameters ---------- radar : pyart.core.Radar Py-ART radar object containing volume scan data. latitude : float, optional Latitude of the point of interest (default is 33.8). longitude : float, optional Longitude of the point of interest (default is -88.3). azimuth_spread : float, optional Azimuthal spread in degrees around the point of interest (default is 3). spatial_spread : float, optional Horizontal spatial spread in kilometers for averaging (default is 3). v_res : float, optional Vertical resolution in meters (default is 100). min_alt : float Minimum altitude in meters. max_alt : float Maximum altitude in meters. Returns ------- xr.Dataset Interpolated columnar vertical profile on a uniform height grid. """ if min_alt is None or max_alt is None: raise ValueError("Both min_alt and max_alt must be specified.") col_prof = pyart.util.column_vertical_profile( radar, latitude=latitude, longitude=longitude, azimuth_spread=azimuth_spread, spatial_spread=spatial_spread, ) new_heights = xr.Dataset( coords={"height": ("height", np.arange(min_alt, max_alt + v_res, v_res))} ) return col_prof.interp_like(new_heights) def rain_rate_categorized( dbz, conv_threshold=40.0, a_conv=300.0, b_conv=1.4, a_strat=200.0, b_strat=1.6 ): """ Computes rain rate from reflectivity, categorizing into convective and stratiform regions. """ Z = 10.0 ** (dbz / 10.0) is_conv = dbz >= conv_threshold rr = xr.zeros_like(Z) rr = xr.where(is_conv, (Z / a_conv) ** (1.0 / b_conv), rr) rr = xr.where(~is_conv, (Z / a_strat) ** (1.0 / b_strat), rr) rr.attrs.update( { "standard_name": "Rain rate", "units": "mm/h", "description": "Rain rate calculated using categorized reflectivity", } ) return rr def download_nexrad(timezone, date, site, local_date=False): """Download NEXRAD radar data from an S3 bucket.""" try: utc_date = ( pytz.timezone(timezone).localize(date).astimezone(pytz.utc) if local_date else date ) logging.info(f"Time: {utc_date}") fs = fsspec.filesystem("s3", anon=True) nexrad_path = utc_date.strftime( f"s3://noaa-nexrad-level2/%Y/%m/%d/{site}/{site}%Y%m%d_%H*" ) files = sorted(fs.glob(nexrad_path)) return [file for file in files if not file.endswith("_MDM")] except Exception as e: logging.error("Error in processing: %s", e) return [] # Load NEXRAD data site = "KGWX" timezone = "UTC" date = datetime(2022, 3, 31, 0, 0) files = download_nexrad(timezone, date, site, local_date=False)[:5] rain_rate_list = [] for file in files: radar = pyart.io.read_nexrad_archive("s3://" + file) col_prof_interp = column_profile( radar, latitude=33.5, longitude=-88.3, azimuth_spread=3, spatial_spread=3, v_res=100, min_alt=200, max_alt=8000, ) rain_rate = rain_rate_categorized(col_prof_interp["reflectivity"]) rain_rate["time"] = col_prof_interp["base_time"] rain_rate_list.append(rain_rate) da_rain_rate = xr.concat(rain_rate_list, dim="time") da_rain_rate.plot.contourf( x="time", levels=range(0, 26, 2), cmap="RRate11", figsize=[10, 3] ) plt.title("QPE") plt.xlabel("Time") plt.ylabel("Height ASL [m]") plt.show() da_rain_rate.sel(height=1000, method="nearest").plot.line("k-", figsize=[10, 3]) plt.title("QPE") plt.xlabel("Time") plt.show() # References # Steiner, M. R., R. A. Houze Jr., and S. E. Yuter, 1995: Climatological # Characterization of Three-Dimensional Storm Structure from Operational # Radar and Rain Gauge Data. J. Appl. Meteor., 34, 1978-2007. # https://doi.org/10.1175/1520-0450(1995)034<1978:CCOTDS>2.0.CO;2. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 19.374 seconds) .. _sphx_glr_download_examples_retrieve_plot_qpe.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_qpe.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_qpe.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_qpe.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_