Investigating ARM Radars¶
Overview¶
Within this notebook, we will cover:
- General structure of radar data
- Radar Scanning
- Look at various ARM radars
- Do a simple analysis
Prerequisites¶
Concepts | Importance | Notes |
---|---|---|
Intro to Cartopy | Helpful | Basic features |
Matplotlib Basics | Helpful | Basic plotting |
NumPy Basics | Helpful | Basic 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).

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.

The sensitivity gains come from the beam with can be approximated as . 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:
This can be broken down to components intrinsic to the radar and the medium:
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:
As long as 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
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 . So
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')