Basic functionality of octant package¶
Import the necessary modules
[1]:
from pathlib import Path
from octant.core import TrackRun, OctantTrack, HOUR
Define the common data directory
[2]:
sample_dir = Path(".") / "sample_data"
Data are usually organised in hierarchical directory structure. Here, the relevant parameters are defined.
[3]:
dataset = "era5"
period = "test"
run_id = 0
Construct the full path
[4]:
track_res_dir = sample_dir / dataset / f"run{run_id:03d}" / period
Load the data¶
The standard loading procedure is done during the initialisation of TrackRun
by reading text files (output from PMCTRACK) from the given directory.
[5]:
tr = TrackRun(track_res_dir)
[6]:
print(tr)
<octant.core.TrackRun>
[671 tracks]
Data columns:
lon | lat | vo | time | area | vortex_type
Sources:
sample_data/era5/run000/test
The TrackRun
object also has an HTML view available in Jupyter Notebooks
[7]:
tr
[7]:
Cyclone tracking results | ||||||
---|---|---|---|---|---|---|
Number of tracks | 671 | |||||
Data columns | lon, lat, vo, time, area, vortex_type | |||||
Sources | ||||||
sample_data/era5/run000/test |
[8]:
type(tr)
[8]:
octant.core.TrackRun
[9]:
len(tr)
[9]:
671
[10]:
tr.size()
[10]:
671
[11]:
tr.tstep_h
[11]:
1.0
Main data container¶
The main attribute of TrackRun
is .data
, which has all the tracks stored in one DataFrame-like object.
[12]:
tr.data.head()
[12]:
lon | lat | vo | time | area | vortex_type | ||
---|---|---|---|---|---|---|---|
track_idx | row_idx | ||||||
0 | 0 | 9.3 | 79.2 | 0.000345 | 2011-01-01 00:00:00 | 10617.93652 | 0 |
1 | 9.3 | 79.2 | 0.000352 | 2011-01-01 01:00:00 | 10154.14648 | 0 | |
2 | 9.3 | 79.2 | 0.000362 | 2011-01-01 02:00:00 | 10136.94629 | 0 | |
1 | 0 | 20.4 | 70.5 | 0.000317 | 2011-01-01 00:00:00 | 34750.66016 | 1 |
1 | 20.7 | 70.5 | 0.000310 | 2011-01-01 01:00:00 | 36727.84375 | 1 |
It always has track_idx
level in order to index through individual tracks.
Tracking run configuration¶
If a .conf
file is present in the same directory, it is loaded to TrackRun
.
[13]:
tr.conf
[13]:
Tracking algorithm settings (43) | |
---|---|
dt_start = | 201101010000 |
dt_end = | 201101312300 |
vor_lvl = | 950 |
steer_lvl_btm = | 1000 |
steer_lvl_top = | 700 |
datadir = | ../../reanalysis/era5 |
outdir = | ../results/test7 |
vort_name = | vo |
u_name = | u |
v_name = | v |
psea_name = | msl |
land_name = | lsm |
prefix_lvl = | era5.an.pl. |
prefix_sfc = | era5.an.sfc. |
proj = | 1 |
vert_grid = | 1 |
lon1 = | -20 |
lon2 = | 50 |
lat1 = | 65 |
lat2 = | 85 |
halo_r = | 30.0 |
smth_type = | 0 |
nsmth_x = | 10 |
nsmth_y = | 10 |
r_smth = | 60.0 |
zeta_max0 = | 0.0002 |
zeta_min0 = | 0.00015 |
int_zeta_min0 = | 2e-06 |
gamma = | 0.25 |
d_cf_min = | 400.0 |
size_synop = | 90000.0 |
distance_ec = | 300.0 |
del_psea_min = | 0.5 |
steering_type = | 2 |
n_steering_x = | 20 |
n_steering_y = | 20 |
r_steering = | 200.0 |
track_type = | 2 |
del_lon = | 1.0 |
del_lat = | 0.8 |
del_r = | 120.0 |
merge_opt = | 2 |
vor_out_on = | 0 |
Other methods of initialisation¶
TrackRun
class can be initialised empty:
[14]:
tr_empty = TrackRun()
[15]:
tr_empty
[15]:
Cyclone tracking results | ||||||
---|---|---|---|---|---|---|
Number of tracks | 0 | |||||
Data columns | lon, lat, vo, time, area, vortex_type |
Concatenate data from several directories¶
TR = TrackRun(one_directory)
TR2 = TrackRun(another_directory)
TR.extend(TR2)
or
TR += TrackRun(another_directory)
Some attributes of TrackRun¶
TrackRun
object has a few useful properties
for example, it is possible to access the list of files that the data were loaded from.
[16]:
tr.filelist[:5]
[16]:
[PosixPath('sample_data/era5/run000/test/vortrack_0001_0001.txt'),
PosixPath('sample_data/era5/run000/test/vortrack_0002_0001.txt'),
PosixPath('sample_data/era5/run000/test/vortrack_0003_0001.txt'),
PosixPath('sample_data/era5/run000/test/vortrack_0004_0001.txt'),
PosixPath('sample_data/era5/run000/test/vortrack_0005_0001.txt')]
there is a shortcut to group tracks by their index
[17]:
tr.gb
[17]:
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fee3dd9f390>
It is equivalent of doing tr.data.groupby("track_idx")
.
[18]:
for idx, a_track in tr.gb:
print(f"Track with index={idx}")
print(a_track)
break
Track with index=0
lon lat vo time area \
track_idx row_idx
0 0 9.3 79.2 0.000345 2011-01-01 00:00:00 10617.93652
1 9.3 79.2 0.000352 2011-01-01 01:00:00 10154.14648
2 9.3 79.2 0.000362 2011-01-01 02:00:00 10136.94629
vortex_type
track_idx row_idx
0 0 0
1 0
2 0
current
TrackRun
is not categorised yet (see “Categorisation” examples), so this attribute is empty:
[19]:
tr.cat_labels
[19]:
[]
Serialising TrackRun¶
TrackRun
and all its metadata can be saved to and loaded from an HDF file.
[20]:
tr.to_archive("test.h5")
[21]:
new_tr = TrackRun.from_archive("test.h5")
[22]:
new_tr
[22]:
Cyclone tracking results | ||||||
---|---|---|---|---|---|---|
Number of tracks | 671 | |||||
Data columns | lon, lat, vo, time, area, vortex_type | |||||
Sources | ||||||
sample_data/era5/run000/test |
Units of TrackRun¶
[23]:
import random
Each cyclone track stored in lists of TrackRun
class as a OctantTrack
instance
[24]:
ot = random.choice([*tr[:].gb])[1]
It is essentially a sub-class of pandas.DataFrame
[25]:
ot
[25]:
lon | lat | vo | time | area | vortex_type | ||
---|---|---|---|---|---|---|---|
track_idx | row_idx | ||||||
124 | 0 | 12.3 | 72.0 | 0.000423 | 2011-01-05 23:00:00 | 7615.17285 | 1 |
1 | 10.8 | 72.0 | 0.000393 | 2011-01-06 00:00:00 | 19943.68750 | 1 | |
2 | 8.7 | 72.0 | 0.000349 | 2011-01-06 01:00:00 | 18887.55273 | 1 | |
3 | -3.6 | 67.2 | 0.000666 | 2011-01-06 02:00:00 | 95968.20312 | 3 |
[26]:
type(ot)
[26]:
octant.core.OctantTrack
It has a few useful properties
[27]:
ot.lifetime_h
[27]:
3.0
[28]:
ot.total_dist_km
[28]:
836.7043121073503
including maximum vorticity in $ s^{-1}$:
[29]:
ot.max_vort
[29]:
0.00066578
[30]:
ot.gen_lys_dist_km
[30]:
810.8722660749592
[31]:
ot.average_speed
[31]:
278.90143736911676
[32]:
ot.lonlat
[32]:
array([[12.3, 72. ],
[10.8, 72. ],
[ 8.7, 72. ],
[-3.6, 67.2]])
Running octant with a progress bar¶
Having either the fastprogress
or tqdm
module installed allows for running some methods with a bar that shows progress. To enable it, set the attribute of RUNTIME
variable to True
:
[33]:
import octant
octant.RUNTIME.enable_progress_bar = True
[34]:
conditions = [
("long_lived", [lambda ot: ot.lifetime_h >= 6]),
(
"far_travelled_and_very_long_lived",
[lambda ot: ot.lifetime_h >= 36, lambda ot: ot.gen_lys_dist_km > 300.0],
),
("strong", [lambda x: x.max_vort > 1e-3]),
]
[35]:
tr.classify(conditions)
More classify()
examples
octant’s utilities¶
[36]:
from octant.utils import great_circle
[37]:
great_circle(lon1=9.6, lon2=10.2, lat1=76.9, lat2=78.9)
[37]:
222826.50759451024