IMD Radar Data#
The India Meteorological Department (IMD) provides radar data in a format similar to IRIS/Sigmet, but with some differences in structure and formatting. radarx
offers specialized support for processing and analyzing this IMD radar data, ensuring compatibility and ease of use despite the variations from standard IRIS/Sigmet formats.
[1]:
import os
import subprocess
import radarx as rx
Load IMD Radar Data#
[2]:
# Base URL for the radar data files on GitHub
base_url = (
"https://raw.githubusercontent.com/syedhamidali/pyscancf_examples/main/data/goa16/"
)
# List of radar data files to download
files = [
"GOA210516024101-IMD-B.nc",
"GOA210516024101-IMD-B.nc.1",
"GOA210516024101-IMD-B.nc.2",
"GOA210516024101-IMD-B.nc.3",
"GOA210516024101-IMD-B.nc.4",
"GOA210516024101-IMD-B.nc.5",
"GOA210516024101-IMD-B.nc.6",
"GOA210516024101-IMD-B.nc.7",
"GOA210516024101-IMD-B.nc.8",
"GOA210516024101-IMD-B.nc.9",
]
# Target directory to save downloaded files
target_dir = os.path.join(os.getenv("GITHUB_WORKSPACE", "."), "radarx_data")
os.makedirs(target_dir, exist_ok=True)
# Function to download files using curl
def download_with_curl(file_name):
file_url = base_url + file_name
file_path = os.path.join(target_dir, file_name)
if not os.path.exists(file_path):
print(f"Downloading {file_name}...")
subprocess.run(["curl", "-o", file_path, file_url], check=True)
print(f"Downloaded {file_name}")
else:
print(f"{file_name} already exists.")
return file_path
# Download the files
downloaded_files = []
for file_name in files:
file_path = download_with_curl(file_name)
downloaded_files.append(file_path)
Downloading GOA210516024101-IMD-B.nc...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1413k 100 1413k 0 0 13.4M 0 --:--:-- --:--:-- --:--:-- 13.2M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Downloaded GOA210516024101-IMD-B.nc
Downloading GOA210516024101-IMD-B.nc.1...
Downloaded GOA210516024101-IMD-B.nc.1
Downloading GOA210516024101-IMD-B.nc.2...
100 1413k 100 1413k 0 0 15.3M 0 --:--:-- --:--:-- --:--:-- 15.3M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1413k 100 1413k 0 0 12.0M 0 --:--:-- --:--:-- --:--:-- 12.0M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Downloaded GOA210516024101-IMD-B.nc.2
Downloading GOA210516024101-IMD-B.nc.3...
Downloaded GOA210516024101-IMD-B.nc.3
Downloading GOA210516024101-IMD-B.nc.4...
100 1413k 100 1413k 0 0 11.3M 0 --:--:-- --:--:-- --:--:-- 11.3M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1413k 100 1413k 0 0 15.8M 0 --:--:-- --:--:-- --:--:-- 15.8M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1413k 100 1413k 0 0 14.0M 0 --:--:-- --:--:-- --:--:-- 14.0M
Downloaded GOA210516024101-IMD-B.nc.4
Downloading GOA210516024101-IMD-B.nc.5...
Downloaded GOA210516024101-IMD-B.nc.5
Downloading GOA210516024101-IMD-B.nc.6...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1413k 100 1413k 0 0 13.5M 0 --:--:-- --:--:-- --:--:-- 13.5M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Downloaded GOA210516024101-IMD-B.nc.6
Downloading GOA210516024101-IMD-B.nc.7...
Downloaded GOA210516024101-IMD-B.nc.7
Downloading GOA210516024101-IMD-B.nc.8...
100 1413k 100 1413k 0 0 15.0M 0 --:--:-- --:--:-- --:--:-- 15.0M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1413k 100 1413k 0 0 12.7M 0 --:--:-- --:--:-- --:--:-- 12.7M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Downloaded GOA210516024101-IMD-B.nc.8
Downloading GOA210516024101-IMD-B.nc.9...
Downloaded GOA210516024101-IMD-B.nc.9
100 1413k 100 1413k 0 0 7639k 0 --:--:-- --:--:-- --:--:-- 7639k
[3]:
print(f"Number of files: {len(downloaded_files)}")
Number of files: 10
Read a Sweep#
[4]:
# Load the first radar file using radarx
swp = rx.io.read_sweep(downloaded_files[0])
swp
[4]:
<xarray.Dataset> Size: 6MB Dimensions: (sweep: 1, time: 360, range: 996) Coordinates: azimuth (time) float32 1kB ... elevation (time) float32 1kB ... * time (time) datetime64[ns] 3kB 2021-05-16T02:41:04 ... ... * range (range) float64 8kB 1e+03 1.25e+03 ... 2.498e+05 Dimensions without coordinates: sweep Data variables: (12/55) time_coverage_start |S20 20B b'2021-05-16T02:41:01Z' fixed_angle (sweep) float32 4B 0.1978 latitude float32 4B ... longitude float32 4B ... altitude float32 4B ... firstGateRange float32 4B 1e+03 ... ... sweep_mode (sweep) |S20 20B b'azimuth_surveillance' scan_type (sweep) |S3 3B b'ppi' time_coverage_end |S20 20B b'2021-05-16T02:41:32Z' sweep_number (sweep) int64 8B 0 sweep_start_ray_index (sweep) int64 8B 0 sweep_end_ray_index (sweep) int64 8B 359 Attributes: Conventions: CF/Radial instrument_parameters version: 1.3 title: institution: India Meteorological Department references: source: comment: im/radarx instrument_name: history: field_names: DBT, DBZ, VEL, WIDTH
We have successfully read one sweep in the above cell. Now, let’s create a volume scan.
Create a Volume#
We have a total of 10 files, each representing a different sweep. Our goal is to combine these individual sweeps into a single CF-Radial volume scan dataset.
[5]:
for file in downloaded_files:
print(os.path.basename(file))
GOA210516024101-IMD-B.nc
GOA210516024101-IMD-B.nc.1
GOA210516024101-IMD-B.nc.2
GOA210516024101-IMD-B.nc.3
GOA210516024101-IMD-B.nc.4
GOA210516024101-IMD-B.nc.5
GOA210516024101-IMD-B.nc.6
GOA210516024101-IMD-B.nc.7
GOA210516024101-IMD-B.nc.8
GOA210516024101-IMD-B.nc.9
[6]:
vol = rx.io.read_volume(downloaded_files)
INFO:radarx.io.imd:Successfully grouped files into 1 sweep groups.
[7]:
vol
[7]:
<xarray.DatasetView> Size: 0B Dimensions: () Data variables: *empty*
We have successfully generated a volume, which can now be explored further. The volume is stored in a DataTree, a high-level structure that organizes and manages the data within the xarray framework.
[8]:
vol.groups
[8]:
('/', '/volume_0')
[9]:
ds = vol["volume_0"].ds
[10]:
ds
[10]:
<xarray.DatasetView> Size: 57MB Dimensions: (time: 3600, range: 996, sweep: 10) Coordinates: azimuth (time) float32 14kB 360.0 0.9943 2.01 ... 358.0 359.0 elevation (time) float32 14kB 0.6372 0.6372 ... 21.4 21.4 * time (time) datetime64[ns] 29kB 2021-05-16T02:41:04 ...... * range (range) float64 8kB 1e+03 1.25e+03 ... 2.498e+05 Dimensions without coordinates: sweep Data variables: (12/55) time_coverage_start |S20 20B b'2021-05-16T02:41:01Z' latitude float32 4B ... longitude float32 4B ... altitude float32 4B ... firstGateRange float32 4B 1e+03 gateSize float32 4B 250.0 ... ... ray_angle_res (sweep) float32 40B 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 sweep_mode (sweep) |S20 200B b'azimuth_surveillance' ... b'az... scan_type (sweep) |S3 30B b'ppi' b'ppi' ... b'ppi' b'ppi' sweep_number (sweep) int64 80B 0 1 2 3 4 5 6 7 8 9 sweep_start_ray_index (sweep) int64 80B 0 360 720 1080 ... 2520 2880 3240 sweep_end_ray_index (sweep) int64 80B 359 719 1079 ... 2879 3239 3599 Attributes: Conventions: CF/Radial instrument_parameters version: 1.3 title: institution: India Meteorological Department references: source: comment: im/radarx instrument_name: history: field_names: DBT, DBZ, VEL, WIDTH
We have successfully created a volume, and we can export it to CF-Radial formatted NetCDF using xarray
.
[11]:
# We can save all these cfradial1 files by iterating over the vol object
outdir = "IMD_OUT"
os.makedirs(outdir, exist_ok=True)
for key in vol.children:
ds = vol[key].ds
time_str = ds.time.min().dt.strftime("%Y%m%d_%H%M%S").item()
ds.to_netcdf(os.path.join(outdir, f"GOA_{time_str}_cfrad1.nc"))
[12]:
os.listdir("IMD_OUT/")
[12]:
['GOA_20210516_024102_cfrad1.nc']
Convert to CF/Radial2#
We can also convert it to cfradial2 data using to_cfradial2 function
[13]:
dtree = rx.io.to_cfradial2_volumes(vol)
[14]:
dtree.groups
[14]:
('/',
'/volume_0',
'/volume_0/radar_parameters',
'/volume_0/georeferencing_correction',
'/volume_0/radar_calibration',
'/volume_0/sweep_0',
'/volume_0/sweep_1',
'/volume_0/sweep_2',
'/volume_0/sweep_3',
'/volume_0/sweep_4',
'/volume_0/sweep_5',
'/volume_0/sweep_6',
'/volume_0/sweep_7',
'/volume_0/sweep_8',
'/volume_0/sweep_9')
[15]:
ds = dtree["volume_0"].ds
[16]:
# Export all the data in a dtree
# for volume in dtree:
# dtree[volume].to_netcdf()