Skip to article frontmatterSkip to article content

Investigating ARM Radars

Investigating ARM Radars

Overview

Within this notebook, we will cover:

  1. General structure of radar data
  2. Radar Scanning
  3. Look at various ARM radars
  4. Do a simple analysis

Prerequisites

ConceptsImportanceNotes
Intro to CartopyHelpfulBasic features
Matplotlib BasicsHelpfulBasic plotting
NumPy BasicsHelpfulBasic arrays
  • Time to learn: 45 minutes

import os
import warnings

import cartopy.crs as ccrs
import matplotlib.pyplot as plt

import matplotlib.pyplot as plt

import pyart
from pyart.testing import get_test_data
import xradar as xd
import numpy as np

warnings.filterwarnings("ignore")

## You are using the Python ARM Radar Toolkit (Py-ART), an open source
## library for working with weather radar data. Py-ART is partly
## supported by the U.S. Department of Energy as part of the Atmospheric
## Radiation Measurement (ARM) Climate Research Facility, an Office of
## Science user facility.
##
## If you use this software to prepare a publication, please cite:
##
##     JJ Helmus and SM Collis, JORS 2016, doi: 10.5334/jors.119

We will use Py-ART to investigate data. This is not a Py-ART tutorial. Also this notebook is limited to moment data and will not cover lower level data such as doppler spectra.

ARM Radars

ARM’s main radars can be broken down into two categories: Scanning and zenith pointing. ARM operates radars at four requency bands: W, Ka, X and C band. ARM denotes radars as either cloud or precipitation sensing. W and Ka are only denoted as cloud sensing, X is both and C is only precipitation sensing. The radars are the Marine W-Band ARM Cloud Radar (M-WACR), Ka band Zenith Radar (Ka-ZR), Ka band ARM Scanning Cloud Radar (Ka-SACR), X band Scanning ARM Radar (X-SACR), X band Scanning ARM Precipition Radar (X-SAPR) and C band Scanning ARM Precipitation Radar (C-SAPR). The notation pertain more to the operation and suitability of the radar (eg there is nothing stopping a user using KAZR to study Precipitation).

alt text

BNF has a C-SAPR, X-SACR, Ka-SACR and a KaZR. Why the different wavelengths? it all comes down to sensitivity, backscatter cross section and if the scattering is in the Reighley regieme where the size of the drops are much smaller than the wavelenth.

alt text

The sensitivity gains come from the beam with can be approximated as θ1.22λD(considering thatsinθθ)\theta\approx 1.22 \frac{\lambda}{D}\quad(\text{considering that}\,\sin\theta\approx\theta). Bigger antenna smaller angle. Shorter wavelength smaller angle. And a smaller angle means you can squeeze more power into a volume.

The power recieved by a radar can be written as:

Pr=π3c1024ln(2)PtG2θ2hκ2Zλ2r2P_r = \frac{\pi^3 c}{1024 \ln(2)} \cdot \frac{P_t G^2 \theta^2 h |\kappa|^2 Z}{\lambda^2 r^2}

This can be broken down to components intrinsic to the radar and the medium:

Pr=PtG2λ2cτ(4π)3Radarπ5K2λ41R2Di6HydrometeorsP_r = \underbrace{\frac{P_t G^2 \lambda^2 c \tau}{(4\pi)^3}}_{\text{Radar}} \underbrace{\frac{\pi^5 |K|^2}{\lambda^4} \frac{1}{R^2} \sum D_i^6}_{\text{Hydrometeors}}

The last component, the sum over all distribited scatters is, as described in the previous talk one of the basic measures from a radar is reflectivity factor:

Z=0DmaxND6dDZ = \int_{0}^{Dmax} N D^6\mathrm{d}D

As long as D<λD < \lambda reflectivity factor is wavelength invariant.

Lets dig into some data to give some examples:

kazr = pyart.io.read('bnfkazr2cfrgeM1.a1.20250422.040000.nc')
csapr.metadata['doi']
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[3], line 1
----> 1 csapr.metadata['doi']

NameError: name 'csapr' is not defined

https://www.osti.gov/dataexplorer/biblio/dataset/1467901-band-scanning-arm-precipitation-radar-generation

Bharadwaj, Nitin, Collis, Scott, Hardin, Joseph, Isom, Bradley, Lindenmaier, Iosif, Matthews, Alyssa, Nelson, Danny, Feng, Ya-Chien, Rocque, Marquette, Wendler, Tim, and Castro, Vagner. C-Band Scanning ARM Precipitation Radar, 2nd Generation. United States: N. p., 2021. Web. doi:10.5439/1467901.

kazr.info()
kazr.fields['reflectivity']

Lets make a plot of the data. Nothing fancy here:

plt.pcolormesh(kazr.fields['reflectivity']['data'])
plt.colorbar()

Lets make it nicer!

my_favorite_colormap = pyart.graph.cmweather.cm_colorblind.ChaseSpectral
plt.pcolormesh(kazr.fields['reflectivity']['data'].transpose(), cmap=my_favorite_colormap)
plt.colorbar()

Being a vertical pointing radar the geometry is simple, a time height cross section.

Lets look at a scanning radar, a Ka band scanning cloud radar.

kasacr = pyart.io.read('bnfkasacrcfrS4.a1.20250422.040001.nc')
plt.pcolormesh(kasacr.fields['reflectivity']['data'].transpose(), cmap=my_favorite_colormap)
plt.colorbar()

ok! This is a little more complex! Here the antenna is moving. Lets look at the geometry.

#Lets look at Azimuth
plt.plot(kasacr.azimuth['data'])
plt.plot(kasacr.elevation['data'])
myd = pyart.graph.RadarDisplay(kasacr)
myd.plot_ppi('reflectivity', cmap=my_favorite_colormap)

Now lets look at C-SAPR

csapr = pyart.io.read('bnfcsapr2cfrS3.a1.20250422.040012.nc')
plt.plot(csapr.azimuth['data'])
mydc = pyart.graph.RadarDisplay(csapr)
mydc.plot_ppi('reflectivity', cmap=my_favorite_colormap)
alt = kazr.gate_z['data']
dbz = kazr.fields['reflectivity']['data']
freq, height_edges, field_edges = np.histogram2d(
        alt.data.flatten(),
        dbz.data.flatten(), 
        bins = [np.linspace(0,15000,99), np.linspace(-60., 20., 79)])
      
X, Y = np.meshgrid(height_edges, field_edges)
plt.pcolormesh(Y, X, freq.transpose(), cmap=my_favorite_colormap)
plt.colorbar()
alt = csapr.gate_z['data']
dbz = csapr.fields['reflectivity']['data']
freq, height_edges, field_edges = np.histogram2d(
        alt.data.flatten(),
        dbz.data.flatten(), 
        bins = [np.linspace(0,15000,99), np.linspace(-40., 40., 79)])

X, Y = np.meshgrid(height_edges, field_edges)
plt.pcolormesh(Y, X, freq.transpose(), cmap=my_favorite_colormap)
plt.colorbar()
alt = kasacr.gate_z['data']
dbz = kasacr.fields['reflectivity']['data']
freq, height_edges, field_edges = np.histogram2d(
        alt.data.flatten(),
        dbz.data.flatten(), 
        bins = [np.linspace(0,2000,39), np.linspace(-40., 40., 39)])

X, Y = np.meshgrid(height_edges, field_edges)
plt.pcolormesh(Y, X, freq.transpose(), cmap=my_favorite_colormap)
plt.colorbar()

Number one rule of reflectivity club: Do math in linear units!

As an example lets look at rainfall retrievals. One of the simplest way of doing a rainfall retrieval is to use a simple power law rainfall relation or, “Z R relation” of the form Z=aRbZ=aR^b. So R=(Z1a)1/bR=(Z \frac{1}{a})^{1/b}

a_value=300.0
b_value=1.4

#Grab reflectivity value
refl = csapr.fields['reflectivity']["data"]

#Make linear reflectivity
linear_refl = 10.0**(refl/10.0)

#Retrieve rain rate
rr_data = ((1.0/a_value) * linear_refl)**(1.0/b_value)

#make a Py-ART field object
rain = pyart.config.get_metadata("radar_estimated_rain_rate")
rain["data"] = rr_data

#Add it back onto the radar object
csapr.add_field('radar_estimated_rain_rate', rain, replace_existing=True)
mydc = pyart.graph.RadarDisplay(csapr)
mydc.plot_ppi('radar_estimated_rain_rate')