5252from shapely .geometry import LineString , MultiLineString , Point
5353from sklearn .metrics import DistanceMetric
5454
55- import climada .hazard .tc_tracks_synth
5655import climada .util .coordinates as u_coord
5756import climada .util .plot as u_plot
58- from climada .hazard import Centroids
57+ from climada .hazard import Centroids , tc_tracks , tc_tracks_synth
5958
6059# climada dependencies
6160from climada .util import ureg
@@ -1621,46 +1620,50 @@ def from_netcdf(cls, folder_name):
16211620 return cls (data )
16221621
16231622 @staticmethod
1624- def compute_central_pressure (basin , v_max ):
1625- """Compute central pressure of tropical cyclone given the maximal
1626- wind speed of the storm. Method needed to load tracks from_netcdf_fast.
1627-
1628- Holland, Greg. (2008). A Revised Hurricane Pressure Wind Model.
1629- Monthly Weather Review - MON WEATHER REV. 136. 10.1175/2008MWR2395.1.
1623+ def define_tc_category_fast (max_sust_wind : np .array , units : str = "kn" ) -> int :
1624+ """Define category of the tropical cyclone according to Saffir-Simpson scale.
16301625
16311626 Parameters:
1632- -----------
1633- basin : str
1634- Basin of generation of the TC
1635- v_max : np.array
1636- 1D vector of maximal wind speed along the track
1627+ ----------
1628+ max_wind : str
1629+ Maximal sustained wind speed
1630+ units: str
1631+ Wind speed units, kn or m/s. Default: kn
16371632
16381633 Returns:
1639- --------
1640- Pc : np.array
1641- 1D vector of central pressure along the track
1634+ -------
1635+ category : int
1636+ -1: "Tropical Depression",
1637+ 0: "Tropical Storm",
1638+ 1: "Hurricane Cat. 1",
1639+ 2: "Hurricane Cat. 2",
1640+ 3: "Hurricane Cat. 3",
1641+ 4: "Hurricane Cat. 4",
1642+ 5: "Hurricane Cat. 5",
16421643 """
1643- a = 3.4
1644- Pn = np .full (len (v_max ), BASIN_ENV_PRESSURE [basin ])
1645- Pc = Pn - (v_max ** (1000 / 644 )) / a
16461644
1647- return Pc
1645+ max_sust_wind = max_sust_wind .astype (
1646+ float
1647+ ) # avoid casting errors if max_sust_wind is int
1648+ max_sust_wind *= 1.943844 if units == "m/s" else 1
16481649
1649- @staticmethod
1650- def compute_radius_max_winds ():
1651- pass
1650+ max_wind = np .nanmax (max_sust_wind )
1651+ category_test = np .full (len (SAFFIR_SIM_CAT ), max_wind ) < np .array (
1652+ SAFFIR_SIM_CAT
1653+ )
1654+ category = np .argmax (category_test ) - 1
16521655
1653- @staticmethod
1654- def define_category_storm (self ):
1655- pass
1656+ return category
16561657
16571658 @classmethod
1658- def from_netcdf_fast (cls , folder_name ):
1659- """Create new TCTracks object from NetCDF files created with the FAST model
1660- of Jonathan Lin.
1661- GitHub Repository: https://github.com/linjonathan/tropical_cyclone_risk?
1659+ def from_fast (cls , folder_name : str ):
1660+ """Create a new TCTracks object from NetCDF files generated by the FAST model, modifying
1661+ the xr.array structure to ensure compatibility with CLIMADA, and calculating the central
1662+ pressure and radius of maximum wind.
1663+
1664+ Model GitHub Repository: https://github.com/linjonathan/tropical_cyclone_risk?
16621665 tab=readme-ov-file
1663- Publication: https://agupubs.onlinelibrary.wiley.com/doi/epdf/10.1029/2023MS003686
1666+ Model Publication: https://agupubs.onlinelibrary.wiley.com/doi/epdf/10.1029/2023MS003686
16641667
16651668 Parameters:
16661669 ----------
@@ -1672,7 +1675,7 @@ def from_netcdf_fast(cls, folder_name):
16721675 Returns:
16731676 -------
16741677 tracks : TCTracks
1675- TCTracks obecjt with tracks data from the given directory of NetCDF files.
1678+ TCTracks object with tracks data from the given directory of NetCDF files.
16761679 """
16771680
16781681 file_tr = get_file_names (folder_name )
@@ -1683,45 +1686,53 @@ def from_netcdf_fast(cls, folder_name):
16831686 continue
16841687 with xr .open_dataset (file ) as ds :
16851688 for i in ds .n_trk :
1686- # if storm_id:
1687- # i == storm_id
16881689
16891690 # Select track
1690- track = ds .sel (n_trk = i . item () )
1691+ track = ds .sel (n_trk = i )
16911692
16921693 # Define coordinates
16931694 lat = track .lat_trks .data
16941695 lon = track .lon_trks .data
16951696 time = track .time .data
16961697
1698+ # Convert time to pandas Datetime "yyyy.mm.dd"
1699+ reference_time = (
1700+ f"{ track .tc_years .item ()} -{ int (track .tc_month .item ())} -01"
1701+ )
1702+ time = pd .to_datetime (time , unit = "s" , origin = reference_time ).astype (
1703+ "datetime64[s]"
1704+ )
1705+
16971706 # Define variables
16981707 time_step_vector = np .full (time .shape [0 ], track .time .data [1 ])
1699- max_sustained_wind = track .v_trks .data
1708+ max_sustained_wind_ms = track .v_trks .data
1709+ max_sustained_wind_knots = max_sustained_wind_ms * 1.943844
17001710 basin_vector = np .full (time .shape [0 ], track .tc_basins .data .item ())
17011711 env_pressure = BASIN_ENV_PRESSURE [track .tc_basins .data .item ()]
17021712 env_pressure_vect = np .full (time .shape [0 ], env_pressure )
17031713
1704- # Define hurricaine category and other attributes
1705- max_sustained_wind_kn = np .nanmax (
1706- max_sustained_wind * 1.943844
1707- ) # convert from m/s to knots
1708- category_test = np .full (
1709- len (SAFFIR_SIM_CAT ), max_sustained_wind_kn
1710- ) < np .array (SAFFIR_SIM_CAT )
1711- category = np .argmax (category_test ) - 1
1712- id_no = track .n_trk .item ()
1713- # Define central pressure
1714- central_pressure = TCTracks .compute_central_pressure (
1715- v_max = max_sustained_wind , basin = track .tc_basins .data .item ()
1714+ cen_pres_missing = np .full (lat .shape , np .nan )
1715+ rmw_missing = np .full (lat .shape , np .nan )
1716+ cen_pres = tc_tracks ._estimate_pressure (
1717+ cen_pres_missing , lat , lon , max_sustained_wind_knots
17161718 )
1719+ rmw = tc_tracks .estimate_rmw (rmw_missing , cen_pres )
1720+
1721+ # Define attributes
1722+ category = tc_tracks .TCTracks .define_tc_category_fast (
1723+ max_sustained_wind_knots
1724+ )
1725+ id_no = track .n_trk .item ()
1726+ track_name = f"storm_{ id_no } "
17171727
17181728 data .append (
17191729 xr .Dataset (
17201730 {
17211731 "time_step" : ("time" , time_step_vector ),
1722- "max_sustained_wind" : ("time" , max_sustained_wind ),
1732+ "max_sustained_wind" : ("time" , max_sustained_wind_ms ),
1733+ "central_pressure" : ("time" , cen_pres ),
1734+ "radius_max_wind" : ("time" , rmw ),
17231735 "environmental_pressure" : ("time" , env_pressure_vect ),
1724- "central_pressure" : ("time" , central_pressure ),
17251736 "basin" : ("time" , basin_vector ),
17261737 },
17271738 coords = {
@@ -1732,8 +1743,10 @@ def from_netcdf_fast(cls, folder_name):
17321743 attrs = {
17331744 "max_sustained_wind_unit" : "m/s" ,
17341745 "central_pressure_unit" : "hPa" ,
1746+ "name" : track_name ,
1747+ "sid" : id_no ,
1748+ "orig_event_flag" : True ,
17351749 "data_provider" : "FAST" ,
1736- "orig_event_flag" : False ,
17371750 "id_no" : id_no ,
17381751 "category" : category ,
17391752 },
0 commit comments