Interpret Hurricane Data contained in HURDAT2
Project description
hurdat2parser -- v2.0.1
An Object-Oriented Approach to Viewing Tropical Cyclone Data
HURDAT2 (https://www.nhc.noaa.gov/data/#hurdat) is a collection of records from individual Tropical Cyclones. The two primary HURDAT2 records are for the Atlantic (since 1850) and East/Central-Pacific Oceans (since 1949).
The purpose of this module is to provide a quick way to analyze the HURDAT2 datasets. It includes methods for retrieving, inspecting, ranking, or even exporting data for seasons, individual storms, or climatological eras.
PyPI Link: https://pypi.org/project/hurdat2parser/
Contents
- Changes/Fixes in this Version (2.1)
- Requirements, Installation, and getting the data
- Importing the module
- HURDAT2 Object Structure
- Methods & Attributes
- Note on Landfall Data
- Roadmap
- Credits
- Copyright/License
Changes in this Version (2.1)
- Restructured module for easier reading/comprehension including addition of 'read-only' variables
- Read-in slightly faster (eliminated separate
forloop for season read-in). - Addition of
<Hurdat2>.basinproperty, a human-readable string that reports the region/location of the hurdat2 file, based on the storms within the record. - Added a
statsmethod for reporting on full or partial statistics and ranks for individual seasons. - Changed former Rank keyword
ascendingtodescending, so that it has the same meaning of thereversekeyword of sorting functions. - Clean-up of ranking methods; concision (generally) and readability improved; significant performance reduction in
rank_climoas it now only collects data that will be reported. - Addition of Season and Tropical Cyclone attributes
cat45reachandcat5reach - fixed small issue in
rank_seasons_thruthat produced minute inaccuracies with track distance related calculations, which was, in-part, incomplete due to an overseen exclusion of a valid distance segment. - shifted
thruargument onrank_seasons_thruto a keyword argument so the positional default keyword parameters would match up torank_seasons - added
hurdat2()methods toSeasonandTropicalCyloneobjects, printing Hurdat2-formatted output.- The former
dump_hurdat2()method ofTCRecordEntrywas changed to justhurdat2()as well.
- The former
- added
__getitem__method toTropicalCyclones; a shortcut to callTCRecordEntryobjects - added flexibility to
TropicalCycloneoutput_geojsonmethod by allowing user to select the type of feature output: point-based or linestring-based. - generated geoJSON files now default to an indention of 2
- fixed typo in code for
SeasongeoJSONmethod where it was substituting MHDP values for ACE. - included
matplotlib-based track maps for individual storms! It's considered experimental, but quite functional. Right now, good for Atlantic and other basins not split by 180deg Longitude. Currently does not include a legend. That is in the plans for the future though. - changed behavior of
__getitem__methods:- if a user is employing the
__getitem__search method, and includes an underscore at the beginning of the storm name, it will return the newest storm where a potential match has been found. Good for referencing notorious storms with retired names. - including a tuple now returns an object based on the length of the tuple
- Length of 1: simply returns the associated
SeasonObject - Length of 2: returns the associated
TropicalCycloneObject - Length of 3: returns the associated
TCRecordEntryObject
- Length of 1: simply returns the associated
- if a user is employing the
TropicalCyclones andTCRecordEntrys are now "self-aware" of parent objects,Season,TropicalCyclonerespectively.- Added representation (
__repr__) magic methods that describe their objects beyond class type and memory address - added
indexproperty forTCRecordEntryobjects; returns the respective<TropicalCyclone>.entry.index()for the entry - gave control to
rank_stormsscoordextentbehavior using a keywordcontains_method.- default of
coordextentis"anywhere", matching if any of the storm's points occurred in the bounding-box. - the
coordextentparameter is still considered experimental
- default of
Installation
- At the command prompt, run
pip install hurdat2parser- When installing, packages
pyshpandgeojsonwill be downloaded as dependencies
- When installing, packages
- You'll then need the actual Hurdat2 Data. You can get it HERE. It's a text file. HURDAT2 files for the Atlantic Basin and East/Central Pacific Basins are available and compatible with the package.
Importing the Module
- Import the module and invoke a call to the
Hurdat2class while passing the file-name of the HURDAT2 dataset
>>> import hurdat2parser
>>> atl = hurdat2parser.Hurdat2("path_to_hurdat2.txt")
-
- For the
Hurdat2object, I highly recommend to use something shortened and readable for the parent object name (likeatloralfor the Atlantic database andep,cp, orpacfor the East/Central Pacific)*
- For the
After a few seconds you'll be ready to dive into the data! Subsequent examples imply the use of the Atlantic Hurdat2.
Hurdat2 Object Structure
- The structure of a
Hurdat2object is hierarchal. It has two primary dictionaries:<Hurdat2>.tc- A dictionary containing allTropicalCycloneobjects compiled from the record.- Individual storms can be accessed using their ATCF ID, a unique 8-character id for each tropical cyclone OR a name of a storm.
atl["AL122005"]- Call for Hurricane Katrina's Data using its ATCFID (it being the 12th storm from the 2005 Atlantic Season).atl["Name"]- Use this if you know the name, but the year is unknown. A partial search is okay, but may receive less accurate results. It uses thedifflibpackage to calculate close matches and outputs a list (if applicable) that you then can select from.atl["_Name"]- including an underscore at the beginning of the name will return the NEWEST storm by a name that matches. Use this for the most-notoroious storms (as it would return the last-so-named storm, retired names included).
- Individual storms can be accessed using their ATCF ID, a unique 8-character id for each tropical cyclone OR a name of a storm.
<Hurdat2>.season- A dictionary holdingSeasonobjects (yearly data).- A Season's data is accessed via a simple year key of type
int.atl[1995]retrieves the object associated with the 1995 hurricane season.
- A Storm's data can also be accessed from this level (quicker than outlined in next section):
atl[2005, 12]- retrieves Hurricane Katrina
- A specific
TCRecordEntrycan be retreived too:atl[2005, 12, 21]- the 22nd entry of Hurricane Katrina
- A Season's data is accessed via a simple year key of type
Seasonobjects also have a dictionary (<Season>.tc) that holdsTropicalCycloneobjects, specific to the year.- There are 4 different ways to access individual storm data:
atl[1995]["Opal"]- Storm Name; Useful if you know the name a storm was issued and the season in which it occurred.atl[1992]["A"]- Storm Name first-letter; I'm not saying you'd forget a named-storm like Hurricane Andrew, but this capability would grab the storm whose first-letter matched the one passed. This primarily works for modern storms (since the beginning of the satellite era), as most in the past were not named. In the HURDAT2 record, storms that were never issued a name are given "UNNAMED" for that field.- TC Number:
atl[1988][8]- Use the storm number (typeint) from the season. This is defined by using the ATCF ID. - ATCF ID:
atl[1980]["AL041980"]- This isn't recommended because of redundancy (it can be done without the initial call to the1980object).
- There are 4 different ways to access individual storm data:
TropicalCycloneobjects contain alistofTCRecordEntryobjects in time-ascending order.- Though the user probably wouldn't have general/typical need to access
TCRecordEntry-level data, it can be done via the desired index from the<TropicalCyclone>.entrylist:atl[2004]["ivan"][0]- This would grab the first entry associated with the track of Hurricane Ivan.
- Though the user probably wouldn't have general/typical need to access
Methods and Attributes
Now that you know how to call a particular object of interest, you can now access its data, using methods and attributes. The docstrings (accessed via help()) are quite detailed and methods that take arguments have example calls listed. But here is a quick reference to what is available, along with some shortcuts and example calls to assist navigating while in this document.
Hurdat2Methods & AttributesSeasonandTropicalCycloneShared Methods & AttributesSeason-only Methods & AttributesTropicalCyclone-only Methods & AttributesTCRecordEntryAttributes
Hurdat2 Methods and Attributes
| Attributes | Description | Examples |
|---|---|---|
rank_seasons(...) |
Print a report that lists a ranking of seasons based on an inquired attribute. Other details are included in the report as well, but they'll be ordered according to the attribute passed. Though not all attributes are represented in the printed report, the ordering will be correct based on the inquired attribute. It also takes positional keyword arguments for year1=None and year2=None, allowing optional ranking to limit the scope of the report to a range of years (this also applies to subsequent ranking methods). |
atl.rank_seasons(5, "track_distance_TS", 1971, 2000, True) |
rank_seasons_thru(...) |
Print a ranking of seasons where you can use part of the season; a way to rank attributes up to or between certain dates. Special keyword arguments, start (internal default of (1,1)) and thru (default of (12, 31)), tuples representing a month and day, (ex. (9,6) for September 6) enable ranking of partial seasons.*As a side note, exclusion of these keywords just make this a wrapper for the above rank_seasons method. |
atl.rank_seasons_thru(10, "TSreach", 1967, thru=(9,30)) |
rank_climo(...) |
Yet another useful ranking method. This allows one to rank attributes assessed over several to many years (climatological periods) to one another. Optional keyword argument climatology (default is 30 years) controls the span of time that data is collected and increment (default is 5 years) dictates the temporal distance between periods |
atl.rank_climo(20,"track_distance_TC", climatology=10, increment=1) |
rank_storms(...) |
Print a report that compares storms and their attributes to each other. Similar to the above methods, other data is included in the report. See the docstring for info on coordextent kw usage |
atl.rank_storms(20,"HDP",1967) |
multi_season_info(...) |
Prints a report a gathered statistics based on a range of years. This is similar to the info() methods referenced in the next section. This could be thought of as an info method for a climatological period |
atl.multi_season_info(1991, 2000)atl[2010, 2019] |
storm_name_search(...) |
Search through the entire HURDAT2 record for storms issued a name. If the positional keyword info is True, the matching storm's info method will print. |
atl.storm_name_search("Hugo") |
output_climo(...) |
outputs a .csv file using the csv package of 1-year incremented climatological periods. This csv file can then be opened in a spreadsheet program. To compare or rank, the spreadsheet GUI layout is much easier to use especially due to instant sorting and filtering. This accepts a positional keyword argument (climatology=30). |
atl.output_climo(15) |
output_seasons_csv(...) |
Similar to the above, but for seasons. It takes no arguments. In other words, it would be redundant to run it multiple times, because as the hurdat2parser package doesn't natively allow modification of the data, it would just output the same data over and over. The only exception would be when the HURDAT2 database is updated by the NHC. With this in mind, it will automatically write-over the csv if it already exists (file-name is auto-generated within the method). |
atl.output_seasons_csv() |
output_storms_csv(...) |
Similar to above, but for individual storms. | atl.output_storms_csv() |
coord_contains(...) |
Takes 3 tupled lat-lon coordinates. The purpose is to inquire whether the first arg (the test coordinate) is contained within a bounding box formed by the other two coordinates passed (returns a bool. This is generally just accessed via the ranking methods |
atl.coord_contains([30.4,-85.0],[31.5, 86.0],[29.0, 84.0]) -> True |
basin |
Interprets and returns a readable string identifying the TC basin based on the storms within the record. This allows support of dynamically-created singular OR multiple Hurdat2 datasets. The data used to form this property came from IBTrACS | `atl.basin -> "North Atlantic Basin" |
record_range |
Returns a tuple of the beginning year and end year of the HURDAT2 record | atl.record_range -> (1851, 2020) |
⇧ back to Methods & Attributes
Shared Methods and Attributes for Season and TropicalCyclone
| Attributes | Description | Examples |
|---|---|---|
output_shp() |
Generate a GIS-compatible Shapefile using the shapefile package |
atl[1988]["Gilbert"].output_shp() |
output_geojson() |
Generate a GIS-compatible and text-readable .geojson file via the geojson package; can also be used in GIS applications |
atl[2000].output_geojson() |
info() |
Prints basic stats | atl[2005].info() |
summary() |
Prints detailed statistics for the season or life of the TC | atl[2019]["dorian"].summary() |
landfalls |
*SEE DISCLAIMER FOR LANDFALL INFO* Sum of all landfalls (remember, a storm can make multiple landfalls). <Season>.landfalls is also an unfiltered aggregate of its storms landfalls. At the seasonal level, you'd probably be more interested in the attribute landfall_TC (see following section) |
atl[1960]["doNnA"].landfalls |
landfall_<STATUS>-can be TC, TD, TS, HU, or MHU |
Season: qty of TC's that made landfall as the inquired status; TropicalCyclone: bool indicating if the storm made landfall while the inquired status-CAUTION: These attrs are exclusive of landfalls made while of stronger designation- |
atl[1996].landfall_TS -> 2atl[2011]["I"].landfall_HU -> True |
<STATUS>reach-can be TC, TD, TS, HU, or MHU |
Season: qty of TC's that reached at least the inquired status; TropicalCyclone: bool indicating if the storm ever was designated as the inquired status |
atl[2010].HUreach -> 12atl[1991]["danny"].HUreach -> False |
ACE, HDP, or MHDP |
Returns the specified Energy Index reading associated with the season or storm. Note that the MHDP is one you likely won't see elsewhere. It's formula is the same as ACE and HDP but for major-hurricanes only | atl[1966].HDP |
track_distance |
The calculated distance (in nmi) for the entire track of the storm (or aggregate of the season), regardless of status | atl[1954]["hazel"].track_distance |
track_distance_<STATUS>-can be TC, TD, TS, HU, or MHU |
The distance traversed while storm(s) was(were) at least the status designation | atl[1961].track_distance_MHU |
cat45reachcat5reach |
For Season objects, returns the quantity of storms that reached category 4+ status or category 5 status (respectively)For TropicalCyclone objects, returns a bool, indicating if the TC ever achieved cat 4+ or 5 status (respectively) |
atl[2020].cat45reach -> 5atl[2020].cat5reach -> 0atl[2020]["Iota"].cat5reach -> False |
maxwind_mslpminmslp_wind |
Returns the MSLP (wind) occurring at the time of peak-winds (minimum MSLP) respectively. These attributes were included because peak winds and minimum MSLP do not necessarily occur at the same time. | atl[2015]["joaquin"].maxwind_mslp -> 934atl[2015]["joaquin"].minmslp_wind -> 120* This example was given as Joaquin's peak winds (135) were not observed at the time of Joaquin's minimum MSLP (931) |
hurdat2() |
This method prints a hurdat2-formatted output of the storms's data, emulating the actual hurdat2 record from which it (the Season or Tropical Cyclone) was created | atl[2005].hurdat2() |
⇧ back to Methods & Attributes
Season Only Methods and Attributes
| Attribute | Description | Example |
|---|---|---|
output_shp_segmented() |
Generates a shapefile including each segment from each tropical-cyclone from a given season; each individual segment from each individual storm will be represented | atl[1932].output_shp_segmented() |
output_geojson_segmented() |
Generates a geojson including each segment from each tropical-cyclone from a given season; each individual segment from each individual storm will be representeds | atl[2003].output_geojson_segmented() |
tracks |
Returns the quantity of tropical cyclones from a season | atl[1995].tracks |
<STATUS>only-can be TD, TS, or HU |
Returns the quantity of TC's from a season that made were given the inquired designation, but never strengthened beyond it. HUonly implies Category 1 and 2 storms only. To inquire about MHU, use the MHUreach attr |
atl[1950].TDonlyatl[2017].HUonly |
stats() |
prints a report filled with statistics and ranks for the season, optionally compared with a subset of seasons and/or partial seasons. | atl[2020].stats()atl[2005].stats(thru=(9,30)) |
⇧ back to Methods & Attributes
TropicalCyclone Only Methods and Attributes
| Attribute | Description | Example |
|---|---|---|
coord_list() |
Prints a report with entry dates and the associated Latitude and Longitude | atl[2005]["rita"].coord_list() |
gps |
Returns a list of tupled latitude and Longitude coordinates |
atl[1998]["MITCH"].coord_list() |
minmslp |
Returns the lowest recorded pressure of the TC | atl[1955][10].minmslp |
<EI>_per_nmi-can be ACE, HDP, or MHDP |
Returns the inquired energy index divided by the track distance covered while the energy index was being contributed to (ACE → track_distance_TS or HDP → track_distance_HU as examples). WARNING! These attributes do not have any kind of threshold controls, so storms which were short-lived can have high values |
atl[1964][10].HDP_per_nmiatl[2016]["matthew"].ACE_per_nmi |
<EI>_perc_ACE → -can be HDP or MHDPHDP_perc_MHDP |
Simply the storm's HDP or MHDP divided by ACE or the MHDP divided by the HDP. Look at this as the percentage (as a float between 0 and 1) of the storm's ACE or HDP that was contributed to while a Hurricane or Major Hurricane, respectively | atl[2017]["IRMA"].HDP_perc_ACE |
track_<EI1>_perc_<EI2>-<EI1> can be TS, HU, or MHU -<EI2> can be TC, TS, HU, or MHU |
Returns the the storm's <EI2> track_distance divided by the track distance while of status <EI1>. <EI1> must be of higher hierarchal status than <EI2> | atl[2005][25].track_HU_perc_TCatl[2003]["Fabian"].track_MHU_perc_TS |
track_map() |
Generates a map of the storm's track using matplotlib. Check the docstring for ways to modify the output to your liking. |
atl["_katrina"].track_map() |
perc_ACEperc_HDPperc_MHDP |
Return the percentage (in decimal form) of the contribution of the storm's ACE, HDP, or MHDP value to the season's value | `atl["_matthew"].perc_MHDP |
⇧ back to Methods & Attributes
TCRecordEntry Attributes
- As mentioned earlier, there's generally no need to access
TCRecordEntryobjects directly. Only the most-common attributes will be referenced in this document. A comprehensive list is available viahelp
| Attribute | Description |
|---|---|
entrytime |
A datetime.datetime object of the entry's timestamp |
status |
The designated 2-letter abbreviation representing the storm's status |
locationlocation_rev |
A tuple of the latitude/longitude coordinates; location_rev is reversed in order, a longitude/latitude tuple; seemingly favored for GIS use. |
wind |
The maximum-sustained winds at the time of entry-recording |
mslp |
The Mean Sea-Level Pressure (in hPa or mb) at the time of entry-recording |
hurdat2() |
Returns a reassembled Hurdat2-formatted string, identical to the one parsed to create the entry |
⇧ back to Methods & Attributes
⇧ back to Contents
Landfall Data
An important point to keep in mind when viewing data and ranking, HURDAT2's landfall data is incomplete. It is progressively being updated in conjunction with the yearly release of the dataset. Please see the documentation HURDAT2 Format Guide for more detail on currently-available landfall data temporal scope.
Roadmap
- Speed-up
<Season>.stats()report; because it employsrank_seasons_thru, and since that is quite snappy, I think thestats()method should be quick too. I'll investigate. - Include a
track_map()method forSeason - Include legends for
<TropicalCyclone>.track_map() - Comparison methods to directly compare one season to another or specific storms to another.
- Formulate a
stats()method forTropicalCyclones (to eventually replace theirinfomethod); including ranking/comparing to storms across the record or a subset of seasons, including arank_storms_thru()companion method forHurdat2objects. - Deprecate
<Season>.info()method (PROBABLY); essentially replaced bystats()method. This may depend on success of attempting to speed up thestatsmethod. - Track distance percentage of season total for
TropicalCyclones - Maybe simpler rank methods so values sought for ranking will guarantee to show
- Inclusion of
matplotlibmethods
Credits
- HURDAT Reference:
Landsea, C. W. and J. L. Franklin, 2013: Atlantic Hurricane Database Uncertainty and Presentation of a New Database Format. Mon. Wea. Rev., 141, 3576-3592. - Haversine Formula (via Wikipedia)
- Bell, et. al. Climate Assessment for 1999. Bulletin of the American Meteorological Society. Vol 81, No. 6. June 2000. S19.
- G. Bell, M. Chelliah. Journal of Climate. Vol. 19, Issue 4. pg 593. 15 February 2006.
- HURDAT2 Format Guide
- Natural Earth GIS Data (data extracted there-from to display maps)
Copyright
Author: Kyle S. Gentry
Copyright © 2019-2021, Kyle Gentry (KyleSGentry@outlook.com)
License: MIT
GitHub: https://github.com/ksgwxfan/hurdat2parser
Author's Webpages:
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hurdat2parser-2.1.tar.gz.
File metadata
- Download URL: hurdat2parser-2.1.tar.gz
- Upload date:
- Size: 187.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.23.0 requests-toolbelt/0.9.1 tqdm/4.20.0 CPython/3.7.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b37f2e4079e138e64fea3f46e8ff556cfa84ae41e47f5b1384e8ae88910131cb
|
|
| MD5 |
4a05a3f5353e73427299e596064ef3cf
|
|
| BLAKE2b-256 |
8f9c52d34f9e9cfee345735ec648d94a52778951b863e47d2b173834fdca9ae3
|
File details
Details for the file hurdat2parser-2.1-py3-none-any.whl.
File metadata
- Download URL: hurdat2parser-2.1-py3-none-any.whl
- Upload date:
- Size: 179.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.23.0 requests-toolbelt/0.9.1 tqdm/4.20.0 CPython/3.7.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5d7240a55dd6f2d6e3dcdaf4d7daa4a1b2a1ced39957d5921c47d263226d3a4
|
|
| MD5 |
911c0babaecdda70b50f6f98a6224add
|
|
| BLAKE2b-256 |
5e3b735ef1e8f05d37ff40dcdc2436e3ba38424c53d5767d86d0deb06d782e26
|