Skip to content

Commit 201daf0

Browse files
Bug fix/storm speed (#104)
* correction for speed and bearing calculation, previously applied computation uniformly for all unique datetimes even though they can be across different forecasts * updated the modified reference files. best-track is unchanged except for the first time which was previously set to be 0, now the next time is propagated backward * handling special case where no previous times available for new forecast * make sure ^Cw is not larger than the maximum radii of the strongest isotach * reformat * Fix tests * check for negative time intervals and use abs for computing speed and forward_azimuth for computing bearing (usually inverse_azimuth) --------- Co-authored-by: SorooshMani-NOAA <soroosh.mani@noaa.gov>
1 parent 4688531 commit 201daf0

24 files changed

+25880
-25846
lines changed

stormevents/nhc/track.py

Lines changed: 57 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,40 +1072,60 @@ def __compute_velocity(data: DataFrame) -> DataFrame:
10721072
for advisory in pandas.unique(data["advisory"]):
10731073
advisory_data = data.loc[data["advisory"] == advisory]
10741074

1075-
indices = numpy.array(
1076-
[
1077-
numpy.where(advisory_data["datetime"] == unique_datetime)[0][0]
1078-
for unique_datetime in pandas.unique(advisory_data["datetime"])
1079-
]
1080-
)
1075+
indices = advisory_data.index
10811076
shifted_indices = numpy.roll(indices, 1)
1082-
shifted_indices[0] = 0
1083-
1084-
indices = advisory_data.index[indices]
1085-
shifted_indices = advisory_data.index[shifted_indices]
1077+
shifted_indices[0] = indices[0]
1078+
1079+
# check for negative time shifts which indicate new forecasts
1080+
# and update this with the last previously available time
1081+
for counter, ind in enumerate(zip(indices, shifted_indices)):
1082+
this_time = advisory_data.loc[ind[0], "datetime"]
1083+
shift_time = advisory_data.loc[ind[1], "datetime"]
1084+
if shift_time > this_time:
1085+
# update shift index
1086+
if (advisory_data["datetime"] < this_time).sum() == 0:
1087+
shifted_indices[counter] = advisory_data["datetime"][
1088+
advisory_data["datetime"] > this_time
1089+
].index[0]
1090+
else:
1091+
shifted_indices[counter] = advisory_data["datetime"][
1092+
advisory_data["datetime"] < this_time
1093+
].index[-1]
10861094

1087-
_, inverse_azimuths, distances = geodetic.inv(
1095+
forward_azimuths, inverse_azimuths, distances = geodetic.inv(
10881096
advisory_data.loc[indices, "longitude"],
10891097
advisory_data.loc[indices, "latitude"],
10901098
advisory_data.loc[shifted_indices, "longitude"],
10911099
advisory_data.loc[shifted_indices, "latitude"],
10921100
)
10931101

1094-
intervals = advisory_data.loc[indices, "datetime"].diff()
1095-
speeds = distances / (intervals / pandas.to_timedelta(1, "s"))
1096-
bearings = pandas.Series(inverse_azimuths % 360, index=speeds.index)
1097-
1098-
for index in indices:
1099-
cluster_index = (
1100-
advisory_data["datetime"] == advisory_data.loc[index, "datetime"]
1102+
intervals = (
1103+
(
1104+
advisory_data.loc[indices, "datetime"].values
1105+
- advisory_data.loc[shifted_indices, "datetime"].values
11011106
)
1102-
advisory_data.loc[cluster_index, "speed"] = speeds[index]
1103-
advisory_data.loc[cluster_index, "direction"] = bearings[index]
1107+
.astype("timedelta64[s]")
1108+
.astype(float)
1109+
)
1110+
speeds = pandas.Series(distances / abs(intervals), index=indices)
1111+
bearings = pandas.Series(inverse_azimuths % 360, index=indices)
1112+
# use forward azimuths for negative intervals
1113+
bearings[intervals < 0] = pandas.Series(
1114+
forward_azimuths[intervals < 0] % 360, index=indices[intervals < 0]
1115+
)
1116+
bearings[pandas.isna(speeds)] = numpy.nan
1117+
# fill in nans carrying forward, because it is same valid time
1118+
# and forecast but different isotach.
1119+
# then fill nans backwards to handle the first time
1120+
speeds.ffill(inplace=True)
1121+
bearings.ffill(inplace=True)
1122+
speeds.bfill(inplace=True)
1123+
bearings.bfill(inplace=True)
1124+
advisory_data["speed"] = speeds
1125+
advisory_data["direction"] = bearings
11041126

11051127
data.loc[data["advisory"] == advisory] = advisory_data
11061128

1107-
data.loc[pandas.isna(data["speed"]), "speed"] = 0
1108-
11091129
return data
11101130

11111131
@property
@@ -1352,7 +1372,21 @@ def clamp(n, minn, maxn):
13521372
or forecast.loc[valid_index, "forecast_hours"].iloc[0] == 0
13531373
):
13541374
continue
1355-
forecast.loc[valid_index, "radius_of_maximum_winds"] = rmw
1375+
# make sure rolling rmw is not larger than the maximum radii of the strongest isotach
1376+
# this problem usually comes from the rolling average
1377+
max_isotach_radii = isotach_radii.loc[valid_index].iloc[-1].max()
1378+
if rmw < max_isotach_radii or numpy.isnan(max_isotach_radii):
1379+
forecast.loc[valid_index, "radius_of_maximum_winds"] = rmw
1380+
# in case it does not come from rolling average just set to be Vr/Vmax ratio of max_isotach_radii
1381+
if (
1382+
forecast.loc[valid_index, "radius_of_maximum_winds"].iloc[-1]
1383+
> max_isotach_radii
1384+
):
1385+
forecast.loc[valid_index, "radius_of_maximum_winds"] = (
1386+
max_isotach_radii
1387+
* forecast.loc[valid_index, "isotach_radius"].iloc[-1]
1388+
/ forecast.loc[valid_index, "max_sustained_wind_speed"].iloc[-1]
1389+
)
13561390

13571391
# fill OFCL background pressure with the first entry from 0-hr CARQ background pressure (at sea level)
13581392
forecast.loc[radp_missing, "background_pressure"] = carq_ref[

stormevents/stormevent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ def __repr__(self) -> str:
516516
return (
517517
f"{self.__class__.__name__}("
518518
f"name={repr(self.name)}, "
519-
f"year={repr(self.year)}, "
519+
f"year={int(self.year)}, "
520520
f"start_date={repr(self.start_date)}, "
521521
f"end_date={repr(self.end_date)}"
522522
f")"

tests/data/reference/test_storm_event_track/florence2018.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 06, 2018083006, , BEST, 0, 128N, 169W, 20, 1008, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 0, 0, L, 0, , 0, 0, INVEST, 1
1+
AL, 06, 2018083006, , BEST, 0, 128N, 169W, 20, 1008, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 0, 0, L, 0, , 270, 5, INVEST, 1
22
AL, 06, 2018083012, , BEST, 0, 128N, 179W, 25, 1007, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 0, 0, L, 0, , 270, 5, SIX, 2
33
AL, 06, 2018083018, , BEST, 0, 128N, 190W, 25, 1007, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 35, 0, L, 0, , 270, 6, SIX, 3
44
AL, 06, 2018083100, , BEST, 0, 131N, 202W, 30, 1006, LO, 0, , 0, 0, 0, 0, 1010, 150, 40, 40, 0, L, 0, , 284, 6, SIX, 4

tests/data/reference/test_storm_event_track/ida2021.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 06, 2018083006, , BEST, 0, 128N, 169W, 20, 1008, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 0, 0, L, 0, , 0, 0, INVEST, 1
1+
AL, 06, 2018083006, , BEST, 0, 128N, 169W, 20, 1008, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 0, 0, L, 0, , 270, 5, INVEST, 1
22
AL, 06, 2018083012, , BEST, 0, 128N, 179W, 25, 1007, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 0, 0, L, 0, , 270, 5, SIX, 2
33
AL, 06, 2018083018, , BEST, 0, 128N, 190W, 25, 1007, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 35, 0, L, 0, , 270, 6, SIX, 3
44
AL, 06, 2018083100, , BEST, 0, 131N, 202W, 30, 1006, LO, 0, , 0, 0, 0, 0, 1010, 150, 40, 40, 0, L, 0, , 284, 6, SIX, 4

tests/data/reference/test_vortex_track/florence2018.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 06, 2018083006, , BEST, 0, 128N, 169W, 20, 1008, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 0, 0, L, 0, , 0, 0, INVEST, 1
1+
AL, 06, 2018083006, , BEST, 0, 128N, 169W, 20, 1008, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 0, 0, L, 0, , 270, 5, INVEST, 1
22
AL, 06, 2018083012, , BEST, 0, 128N, 179W, 25, 1007, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 0, 0, L, 0, , 270, 5, SIX, 2
33
AL, 06, 2018083018, , BEST, 0, 128N, 190W, 25, 1007, LO, 0, , 0, 0, 0, 0, 1010, 150, 50, 35, 0, L, 0, , 270, 6, SIX, 3
44
AL, 06, 2018083100, , BEST, 0, 131N, 202W, 30, 1006, LO, 0, , 0, 0, 0, 0, 1010, 150, 40, 40, 0, L, 0, , 284, 6, SIX, 4

tests/data/reference/test_vortex_track/harvey2017.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 09, 2017081606, , BEST, 0, 137N, 458W, 25, 1013, LO, 0, , 0, 0, 0, 0, 1014, 150, 80, 0, 0, ,,, 0, 0,, 1
1+
AL, 09, 2017081606, , BEST, 0, 137N, 458W, 25, 1013, LO, 0, , 0, 0, 0, 0, 1014, 150, 80, 0, 0, ,,, 270, 8,, 1
22
AL, 09, 2017081612, , BEST, 0, 137N, 474W, 25, 1010, LO, 0, , 0, 0, 0, 0, 1013, 150, 80, 0, 0, L, 0, , 270, 8, INVEST, 2
33
AL, 09, 2017081618, , BEST, 0, 136N, 490W, 25, 1009, LO, 0, , 0, 0, 0, 0, 1013, 150, 80, 0, 0, L, 0, , 267, 8, INVEST, 3
44
AL, 09, 2017081700, , BEST, 0, 136N, 506W, 25, 1010, LO, 0, , 0, 0, 0, 0, 1012, 120, 80, 0, 0, L, 0, , 270, 8, INVEST, 4

tests/data/reference/test_vortex_track/ike2008.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 09, 2008090106, , BEST, 0, 172N, 370W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1011, 250, 90, 0, 0, L, 0, , 0, 0, INVEST, 1
1+
AL, 09, 2008090106, , BEST, 0, 172N, 370W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1011, 250, 90, 0, 0, L, 0, , 274, 7, INVEST, 1
22
AL, 09, 2008090112, , BEST, 0, 173N, 384W, 35, 1005, TS, 34, NEQ, 120, 75, 0, 60, 1011, 250, 90, 40, 0, L, 0, , 274, 7, NINE, 2
33
AL, 09, 2008090118, , BEST, 0, 175N, 399W, 45, 1003, TS, 34, NEQ, 130, 110, 0, 75, 1011, 250, 90, 55, 0, L, 0, , 278, 7, IKE, 3
44
AL, 09, 2008090200, , BEST, 0, 178N, 413W, 45, 1002, TS, 34, NEQ, 140, 120, 0, 90, 1011, 250, 20, 55, 0, L, 0, , 283, 7, IKE, 4

tests/data/reference/test_vortex_track/irene2011.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 09, 2011082100, , BEST, 0, 150N, 590W, 45, 1006, TS, 34, NEQ, 105, 0, 0, 45, 1010, 175, 60, 55, 0, L, 0, , 0, 0, IRENE, 1
1+
AL, 09, 2011082100, , BEST, 0, 150N, 590W, 45, 1006, TS, 34, NEQ, 105, 0, 0, 45, 1010, 175, 60, 55, 0, L, 0, , 303, 9, IRENE, 1
22
AL, 09, 2011082106, , BEST, 0, 160N, 606W, 45, 1006, TS, 34, NEQ, 130, 0, 0, 80, 1010, 175, 50, 55, 0, L, 0, , 303, 9, IRENE, 2
33
AL, 09, 2011082112, , BEST, 0, 168N, 622W, 45, 1005, TS, 34, NEQ, 130, 0, 0, 70, 1010, 175, 50, 55, 0, L, 0, , 298, 9, IRENE, 3
44
AL, 09, 2011082118, , BEST, 0, 175N, 637W, 50, 999, TS, 34, NEQ, 130, 20, 0, 70, 1010, 175, 50, 55, 0, L, 0, , 296, 8, IRENE, 4

tests/data/reference/test_vortex_track/irma2017.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 11, 2017083000, , BEST, 0, 161N, 269W, 30, 1008, TD, 0, , 0, 0, 0, 0, 1012, 180, 60, 0, 0, L, 0, , 0, 0, INVEST, 1
1+
AL, 11, 2017083000, , BEST, 0, 161N, 269W, 30, 1008, TD, 0, , 0, 0, 0, 0, 1012, 180, 60, 0, 0, L, 0, , 274, 7, INVEST, 1
22
AL, 11, 2017083006, , BEST, 0, 162N, 283W, 35, 1007, TS, 34, NEQ, 30, 0, 0, 0, 1012, 180, 60, 0, 0, L, 0, , 274, 7, INVEST, 2
33
AL, 11, 2017083012, , BEST, 0, 163N, 297W, 45, 1006, TS, 34, NEQ, 30, 0, 0, 30, 1012, 180, 20, 50, 0, L, 0, , 274, 7, IRMA, 3
44
AL, 11, 2017083018, , BEST, 0, 163N, 308W, 50, 1004, TS, 34, NEQ, 30, 30, 0, 30, 1011, 200, 15, 0, 0, L, 0, , 270, 5, IRMA, 4

tests/data/reference/test_vortex_track/isabel2003.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 13, 2003090600, , BEST, 0, 138N, 314W, 30, 1009, TD, 34, NEQ, 0, 0, 0, 0, 1012, 150, 40, 0, 0, ,,, 0, 0,, 1
1+
AL, 13, 2003090600, , BEST, 0, 138N, 314W, 30, 1009, TD, 34, NEQ, 0, 0, 0, 0, 1012, 150, 40, 0, 0, ,,, 275, 7,, 1
22
AL, 13, 2003090606, , BEST, 0, 139N, 327W, 35, 1005, TS, 34, NEQ, 0, 0, 0, 0, 1012, 150, 40, 0, 0, ,,, 275, 7,, 2
33
AL, 13, 2003090612, , BEST, 0, 136N, 339W, 40, 1003, TS, 34, NEQ, 75, 75, 25, 75, 1012, 150, 25, 0, 0, ,,, 256, 6,, 3
44
AL, 13, 2003090618, , BEST, 0, 134N, 349W, 45, 1000, TS, 34, NEQ, 75, 75, 25, 75, 1012, 150, 25, 0, 0, ,,, 259, 5,, 4

tests/data/reference/test_vortex_track/maria2017.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 15, 2017091612, , BEST, 0, 122N, 497W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1012, 150, 40, 40, 0, L, 0, , 0, 0, INVEST, 1
1+
AL, 15, 2017091612, , BEST, 0, 122N, 497W, 30, 1006, TD, 0, , 0, 0, 0, 0, 1012, 150, 40, 40, 0, L, 0, , 270, 10, INVEST, 1
22
AL, 15, 2017091618, , BEST, 0, 122N, 517W, 40, 1004, TS, 34, NEQ, 40, 0, 0, 40, 1012, 150, 40, 50, 0, L, 0, , 270, 10, FIFTEEN, 2
33
AL, 15, 2017091700, , BEST, 0, 124N, 531W, 45, 1002, TS, 34, NEQ, 40, 30, 0, 40, 1012, 150, 30, 55, 0, L, 0, , 278, 7, MARIA, 3
44
AL, 15, 2017091706, , BEST, 0, 128N, 544W, 55, 994, TS, 34, NEQ, 50, 40, 0, 50, 1010, 150, 20, 65, 0, L, 0, , 288, 7, MARIA, 4

tests/data/reference/test_vortex_track/michael2018.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 14, 2018100618, , BEST, 0, 178N, 866W, 25, 1006, LO, 0, , 0, 0, 0, 0, 1009, 180, 90, 35, 0, L, 0, , 0, 0, INVEST, 1
1+
AL, 14, 2018100618, , BEST, 0, 178N, 866W, 25, 1006, LO, 0, , 0, 0, 0, 0, 1009, 180, 90, 35, 0, L, 0, , 316, 2, INVEST, 1
22
AL, 14, 2018100700, , BEST, 0, 181N, 869W, 25, 1004, LO, 0, , 0, 0, 0, 0, 1009, 180, 90, 35, 0, L, 0, , 316, 2, FOURTEEN, 2
33
AL, 14, 2018100706, , BEST, 0, 184N, 868W, 30, 1004, TD, 0, , 0, 0, 0, 0, 1010, 240, 120, 40, 0, L, 0, , 18, 2, FOURTEEN, 3
44
AL, 14, 2018100712, , BEST, 0, 188N, 864W, 35, 1003, TS, 34, NEQ, 120, 180, 0, 0, 1009, 270, 120, 40, 0, L, 0, , 44, 3, FOURTEEN, 4

tests/data/reference/test_vortex_track/sandy2012.fort.22

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AL, 18, 2012102118, , BEST, 0, 143N, 774W, 25, 1006, LO, 0, , 0, 0, 0, 0, 1008, 180, 150, 35, 0, L, 0, , 0, 0, INVEST, 1
1+
AL, 18, 2012102118, , BEST, 0, 143N, 774W, 25, 1006, LO, 0, , 0, 0, 0, 0, 1008, 180, 150, 35, 0, L, 0, , 224, 3, INVEST, 1
22
AL, 18, 2012102200, , BEST, 0, 139N, 778W, 25, 1005, LO, 0, , 0, 0, 0, 0, 1008, 180, 150, 35, 0, L, 0, , 224, 3, INVEST, 2
33
AL, 18, 2012102206, , BEST, 0, 135N, 782W, 25, 1003, LO, 0, , 0, 0, 0, 0, 1008, 225, 75, 35, 0, L, 0, , 224, 3, INVEST, 3
44
AL, 18, 2012102212, , BEST, 0, 131N, 786W, 30, 1002, TD, 0, , 0, 0, 0, 0, 1007, 250, 75, 0, 0, L, 0, , 224, 3, EIGHTEEN, 4

0 commit comments

Comments
 (0)