Skip to content

Commit 1aba273

Browse files
authored
Merge pull request #46 from wx4stg/lmainterceptrhi
Allow user-specified lat/lon/alt of points for lma_intercept_rhi
2 parents f392af2 + f41ffda commit 1aba273

3 files changed

Lines changed: 309 additions & 16 deletions

File tree

examples/lma_intercept_rhi.ipynb

Lines changed: 232 additions & 0 deletions
Large diffs are not rendered by default.

pyxlma/lmalib/lma_intercept_rhi.py

Lines changed: 76 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from pyxlma.coords import RadarCoordinateSystem, TangentPlaneCartesianSystem, GeographicSystem
2-
import numpy as np
2+
import numpy as np
3+
import datetime as dt
4+
import pandas as pd
35

46

57
def rcs_to_tps(radar_latitude, radar_longitude, radar_altitude, radar_azimuth):
@@ -58,15 +60,15 @@ def rcs_to_tps(radar_latitude, radar_longitude, radar_altitude, radar_azimuth):
5860
return X, Y, Z
5961

6062

61-
def geo_to_tps(lma_file, tps_latitude, tps_longitude, tps_altitude):
63+
def geo_to_tps(event_longitude, event_latitude, event_altitude, tps_latitude, tps_longitude, tps_altitude):
6264
"""
6365
Convert the latitude, longitude, and altitude of LMA VHF sources to x/y/z distances (in meters) from an arbitrary latitude, longitude, and altitude.
6466
6567
Creates a tangent plane cartesian system at the latitude, longitude, and altitude provided, and converts the LMA VHF sources to the tangent plane coordinate system.
6668
6769
Parameters
6870
----------
69-
lma_file : `xarray.Dataset`
71+
event_longitude : `xarray.Dataset`
7072
A pyxlma dataset containing latitude, longitude, and altitude of LMA VHF sources.
7173
tps_latitude : `float`
7274
Latitude of the tangent plane in degrees.
@@ -91,7 +93,7 @@ def geo_to_tps(lma_file, tps_latitude, tps_longitude, tps_altitude):
9193

9294
# GEO to TPS
9395

94-
d, e, h = geo.toECEF(lma_file.event_longitude.data, lma_file.event_latitude.data, lma_file.event_altitude.data)
96+
d, e, h = geo.toECEF(event_longitude, event_latitude, event_altitude)
9597

9698

9799
deh = np.vstack((d,e,h))
@@ -104,7 +106,7 @@ def geo_to_tps(lma_file, tps_latitude, tps_longitude, tps_altitude):
104106
return Xlma,Ylma,Zlma
105107

106108

107-
def ortho_proj_lma(lma_file, radar_latitude, radar_longitude, radar_altitude, radar_azimuth):
109+
def ortho_proj_lma(event_longitude, event_latitude, event_altitude, radar_latitude, radar_longitude, radar_altitude, radar_azimuth):
108110
"""
109111
Convert the latitude, longitude, and altitude of LMA VHF sources to distance along, distance from, and height above the ground of a radar RHI scan.
110112
@@ -130,7 +132,7 @@ def ortho_proj_lma(lma_file, radar_latitude, radar_longitude, radar_altitude, ra
130132
A Nx3 array representing the distance along, distance from, and height above the ground (in m) of the LMA VHF sources.
131133
132134
"""
133-
Xlma,Ylma,Zlma = geo_to_tps(lma_file, radar_latitude, radar_longitude, radar_altitude)
135+
Xlma,Ylma,Zlma = geo_to_tps(event_longitude, event_latitude, event_altitude, radar_latitude, radar_longitude, radar_altitude)
134136
X, Y, Z = rcs_to_tps(radar_latitude, radar_longitude, radar_altitude, radar_azimuth)
135137

136138
lon_ini1 = X[0,0]
@@ -179,7 +181,7 @@ def ortho_proj_lma(lma_file, radar_latitude, radar_longitude, radar_altitude, ra
179181
lma_file_loc[:,0] = np.sqrt(lma_file_loc_par[:,0]**2 + lma_file_loc_par[:,1]**2)
180182
if radar_azimuth <= 90 or radar_azimuth >= 270:
181183
lma_file_loc[:,0][lma_file_loc_par[:,1] < 0] = -lma_file_loc[:,0][lma_file_loc_par[:,1] < 0]
182-
elif radar_azimuth > 180 and radar_azimuth < 270:
184+
elif radar_azimuth >= 180 and radar_azimuth < 270:
183185
lma_file_loc[:,0][lma_file_loc_par[:,0] > 0] = -lma_file_loc[:,0][lma_file_loc_par[:,0] > 0]
184186
else:
185187
lma_file_loc[:,0][lma_file_loc_par[:,0] < 0] = -lma_file_loc[:,0][lma_file_loc_par[:,0] < 0]
@@ -189,7 +191,9 @@ def ortho_proj_lma(lma_file, radar_latitude, radar_longitude, radar_altitude, ra
189191
return lma_file_loc
190192

191193

192-
def find_points_near_rhi(lma_file, radar_latitude, radar_longitude, radar_altitude, radar_azimuth, radar_scan_time, distance_threshold=1000, time_threshold=30):
194+
def find_points_near_rhi(event_longitude, event_latitude, event_altitude, event_time,
195+
radar_latitude, radar_longitude, radar_altitude, radar_azimuth, radar_scan_time,
196+
distance_threshold=1000, time_threshold=30):
193197
"""
194198
Find the LMA VHF sources near a radar RHI scan.
195199
@@ -199,8 +203,14 @@ def find_points_near_rhi(lma_file, radar_latitude, radar_longitude, radar_altitu
199203
200204
Parameters
201205
----------
202-
lma_file : `xarray.Dataset`
203-
A pyxlma dataset containing latitude, longitude, and altitude, and event_id of N number of LMA VHF sources.
206+
event_longitude : array-like
207+
An array of the latitudes of events to be transformed.
208+
event_latitude : array-like
209+
An array of the latitudes of events to be transformed.
210+
event_altitude : array-like
211+
An array of the altitudes of events to be transformed.
212+
event_time : array-like
213+
An array of the times of events to be transformed.
204214
radar_latitude : `float`
205215
Latitude of the radar in degrees.
206216
radar_longitude : `float`
@@ -231,17 +241,68 @@ def find_points_near_rhi(lma_file, radar_latitude, radar_longitude, radar_altitu
231241

232242
radar_azimuth = radar_azimuth % 360
233243

234-
radar_scan_time = np.array([radar_scan_time]).astype('datetime64[s]')
244+
radar_scan_time = np.array([radar_scan_time]).astype('datetime64[s]').astype(dt.datetime)
235245

236-
projected_lma = ortho_proj_lma(lma_file, radar_latitude, radar_longitude, radar_altitude, radar_azimuth)
246+
projected_lma = ortho_proj_lma(event_longitude, event_latitude, event_altitude,
247+
radar_latitude, radar_longitude, radar_altitude, radar_azimuth)
237248
lma_range = projected_lma[:,0]
238249
lma_dist = projected_lma[:,1]
239250
lma_alt = projected_lma[:,2]
240251

241-
lma_times = lma_file.event_time.data.astype('datetime64[s]')
242-
point_mask = (lma_dist < distance_threshold) & (np.abs(lma_times - radar_scan_time).astype(float) < time_threshold)
252+
if isinstance(event_time, pd.Series):
253+
event_time = event_time.values
254+
lma_times = event_time.astype('datetime64[s]').astype(dt.datetime)
255+
point_mask = np.ones_like(lma_range, dtype=bool)
256+
if distance_threshold is not None:
257+
point_mask = np.logical_and(point_mask, lma_dist < distance_threshold)
258+
if time_threshold is not None:
259+
point_mask = np.logical_and(point_mask,
260+
np.abs(lma_times - radar_scan_time) < dt.timedelta(seconds=time_threshold))
243261
lma_range = lma_range[point_mask]
244262
lma_dist = lma_dist[point_mask]
245263
lma_alt = lma_alt[point_mask]
246-
247264
return lma_range, lma_dist, lma_alt, point_mask
265+
266+
267+
def find_lma_points_near_rhi(lma_file, radar_latitude, radar_longitude, radar_altitude, radar_azimuth, radar_scan_time, distance_threshold=1000, time_threshold=30):
268+
"""
269+
Find the LMA VHF sources near a radar RHI scan.
270+
271+
Creates tangent plane at the radar's location and converts the LMA VHF sources to the tangent plane coordinate system, then rotates the tangent plane in the direction of the scan azimuth.
272+
Filters RHI scan points based on distance and time thresholds.
273+
274+
275+
Parameters
276+
----------
277+
lma_file : `xarray.Dataset`
278+
A pyxlma dataset containing latitude, longitude, and altitude, and event_id of N number of LMA VHF sources.
279+
radar_latitude : `float`
280+
Latitude of the radar in degrees.
281+
radar_longitude : `float`
282+
Longitude of the radar in degrees.
283+
radar_altitude : `float`
284+
Altitude of the radar in meters.
285+
radar_azimuth : `float`
286+
Azimuth of the RHI scan in degrees.
287+
radar_scan_time : `datetime.datetime` or `numpy.datetime64` or `pandas.Timestamp`
288+
Time of the RHI scan.
289+
distance_threshold : `float`
290+
Maximum distance from the radar to the LMA VHF sources in meters. Default is 1000.
291+
time_threshold : `float`
292+
Number of seconds before and after the RHI scan time to include LMA VHF sources. Default is 30. (total length: 1 minute)
293+
294+
295+
Returns
296+
----------
297+
lma_range : `numpy.ndarray`
298+
A 1D array representing the distance along the tangent plane in the direction of the RHI scan.
299+
lma_dist : `numpy.ndarray`
300+
A 1D array representing the distance from the radar RHI scan plane to each filtered LMA point.
301+
lma_alt : `numpy.ndarray`
302+
A 1D array representing the height above the tangent plane centered at radar level of each filtered LMA point.
303+
point_mask : `numpy.ndarray`
304+
A 1D array of booleans representing the VHF points that were included in the return.
305+
"""
306+
return find_points_near_rhi(lma_file.event_longitude.data, lma_file.event_latitude.data, lma_file.event_altitude.data,
307+
lma_file.event_time.data, radar_latitude, radar_longitude, radar_altitude, radar_azimuth,
308+
radar_scan_time, distance_threshold, time_threshold)

tests/test_intercept_rhi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def test_intercept_rhi():
1111
files_to_read = listdir('examples/data/')
1212
files_to_read = ['examples/data/'+file for file in files_to_read]
1313
dataset, start_date = lma_read.dataset(files_to_read)
14-
lma_radar_range, lma_plane_distance, lma_arl, event_mask = lma_intercept_rhi.find_points_near_rhi(dataset, 33.56, -101.81, 1600.0, 225, start_date+timedelta(seconds=30), distance_threshold=500, time_threshold=15)
14+
lma_radar_range, lma_plane_distance, lma_arl, event_mask = lma_intercept_rhi.find_lma_points_near_rhi(dataset, 33.56, -101.81, 1600.0, 225, start_date+timedelta(seconds=30), distance_threshold=500, time_threshold=15)
1515
lma_indices = np.flatnonzero(event_mask)
1616
true_radar_range = np.array([-24314.95714263, -24255.42134556, -23947.00309296, -24201.07999466,
1717
-24216.22494555, -24209.0779143 , -24252.54770026, -24196.90100367,

0 commit comments

Comments
 (0)