Flight plan - HALO-20240825a

Contents

Flight plan - HALO-20240825a#

ec_under ec_track ec_north c_north c_mid c_south c_atr ocsm

Crew#

The flight is planned to take off at 2024-08-25 09:15:00+00:00.

Job

Name

PI

Julia Windmiller

WALES

Tanja Bodenbach

HAMP

Jakob Deutloff

Dropsondes

Theresa Mieslinger

Smart/VELOX

Kevin Wolf

SpecMACS

Lea Volkmer

Flight Documentation

Suelly Katiza

Ground contact

Nicolas Rochetin

Flight plan#

Hide code cell source
import intake
import easygems.healpix as egh
from datetime import datetime, timedelta
import numpy as np

import matplotlib.pyplot as plt
import cartopy.crs as ccrs

import orcestra.sat
import orcestra.flightplan as fp
from orcestra.flightplan import LatLon, IntoCircle, bco, sal, mindelo, find_ec_lon, vertical_preview, to_kml

# Define dates for forecast initialization and flight

issued_time = datetime(2024, 8, 24, 0, 0, 0)
flight_time = datetime(2024, 8, 25, 12, 0, 0)
flight_index = f"HALO-{flight_time.strftime('%Y%m%d')}a"

print(
    f"Initalization date of IFS forecast: {issued_time}\n"
    f"Flight date: {flight_time:%Y-%m-%d}\n"
    f"Flight index: {flight_index}"
)

# Load forecast data
cat = intake.open_catalog("https://tcodata.mpimet.mpg.de/internal.yaml")
ds = cat.HIFS(datetime = issued_time).to_dask().pipe(egh.attach_coords)

# Load ec satellite track for 
ec_track = orcestra.sat.SattrackLoader("EARTHCARE", "2024-08-24", kind="PRE").get_track_for_day(f"{flight_time:%Y-%m-%d}")
ec_track = ec_track.sel(time=slice(f"{flight_time:%Y-%m-%d} 06:00", None))
ec_lons, ec_lats = ec_track.lon.values, ec_track.lat.values

# Domain definition
lon_min, lon_max, lat_min, lat_max = -65, -5, -10, 25

## Setting lat/lon coordinates

# Mass flux circle radius (m)
radius = 130e3
atr_radius = 70e3

# Setting region (Cabo Verde vs. Barbados)
airport = sal #bco

# Latitudes where we enter and leave the ec track (visually estimated)
lat_ec_north_out = 16.0
lat_ec_north_in = 12.0
lat_ec_south = 2.5

# ITCZ edges visually estimated from iwv contours
lat_c_south = 4.0
lat_c_north = 10.0

# Extra Points along the flight track
lat_c_south_alt_s = 3.25
lat_c_south_alt_n = 4.75

lat_c_north_alt_s = 9.25
lat_c_north_alt_n = 10.75

# Extra Points off the flight track
lat_ec_south_alt = 2.0

# Setting lat/lon coordinates

# Points where we get on ec track
north_ec_in = LatLon(lat_ec_north_in, find_ec_lon(lat_ec_north_in, ec_lons, ec_lats), label = "north_ec_in")
north_ec_out = LatLon(lat_ec_north_out, find_ec_lon(lat_ec_north_out, ec_lons, ec_lats), label = "north_ec_out")
south_ec = LatLon(lat_ec_south, find_ec_lon(lat_ec_south, ec_lons, ec_lats), label = "south_ec")

# Intersection of ITCZ edges with ec track
c_north = LatLon(lat_c_north, find_ec_lon(lat_c_north, ec_lons, ec_lats), label = "c_north")
c_south = LatLon(lat_c_south, find_ec_lon(lat_c_south, ec_lons, ec_lats), label = "c_south")

# Center of middle circle
c_mid = c_south.towards(c_north).assign(label = "c_mid")

# EarthCARE underpass
ec_under = c_north.towards(north_ec_out)
ec_under = LatLon(ec_under.lat, find_ec_lon(ec_under.lat, ec_lons, ec_lats), label = "ec_under")

# ATR circle
atr_circ_sar = LatLon(lat=15.5, lon=-22.1, label="atr_sar")

# Extra Points along the way
c_south_alt_s = LatLon(lat_c_south_alt_s, find_ec_lon(lat_c_south_alt_s, ec_lons, ec_lats), label = "c_south_alt_s")
c_south_alt_n = LatLon(lat_c_south_alt_n, find_ec_lon(lat_c_south_alt_n, ec_lons, ec_lats), label = "c_south_alt_n")

c_north_alt_s = LatLon(lat_c_north_alt_s, find_ec_lon(lat_c_north_alt_s, ec_lons, ec_lats), label = "c_north_alt_s")
c_north_alt_n = LatLon(lat_c_north_alt_n, find_ec_lon(lat_c_north_alt_n, ec_lons, ec_lats), label = "c_north_alt_n")

# Extra Points 
ec_south_alt = LatLon(lat_ec_south_alt, find_ec_lon(lat_ec_south_alt, ec_lons, ec_lats), label = "south_ec_alt")

# Define flight track, can be split into different legs
take_off_time = '2024-08-25T09:15:00Z'
waypoints = [
     airport.assign(time=take_off_time), 
     north_ec_in.assign(fl=400),
     c_north.assign(fl=400),
     c_mid.assign(fl=400),
     c_south.assign(fl=400),
     south_ec.assign(fl=430),
     c_south_alt_s.assign(fl=430),
     IntoCircle(c_south.assign(fl=430), radius, 360),  
     c_south_alt_n.assign(fl=430),
     IntoCircle(c_mid.assign(fl=430), radius, 360), 
     c_north_alt_s.assign(fl=430),
     IntoCircle(c_north.assign(fl=450), radius, 360),
     c_north_alt_n.assign(fl=450),
     ec_under.assign(fl=450),
     north_ec_out.assign(fl=450),
     mindelo.assign(fl=450),
     IntoCircle(atr_circ_sar.assign(fl=350), atr_radius, 360),
     airport
] 

path = fp.expand_path(waypoints, dx=10e3)

# Plot flight path

plt.figure(figsize = (12, 8))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_extent([lon_min, lon_max, lat_min, lat_max], crs=ccrs.PlateCarree())
ax.coastlines(alpha=1.0)
ax.gridlines(draw_labels=True, dms=True, x_inline=False, y_inline=False, alpha = 0.25)

cwv_flight_time = ds["tcwv"].sel(time=flight_time, method = "nearest")
fp.plot_cwv(cwv_flight_time, levels = [45.0, 48.0, 50.0, 52.0, 54.0])
plt.title(f"{flight_time}\n(CWV forecast issued on {issued_time})")

plt.plot(ec_lons, ec_lats)
fp.plot_path(path, ax, color="C1")
Initalization date of IFS forecast: 2024-08-24 00:00:00
Flight date: 2024-08-25
Flight index: HALO-20240825a
/home/runner/miniconda3/envs/orcestra_book/lib/python3.12/site-packages/orcestra/sat.py:180: UserWarning: You are using an old forecast (issued on 2024-08-24) for EARTHCARE on 2024-08-25! The newest forecast issued so far was issued on 2024-08-25. It's a RES forecast.
  warnings.warn(
../_images/ac31e861366bd2365442d081f8cb187765b742f5120281002a9a0cce3b76db6b.png
Hide code cell source
vertical_preview(waypoints)
plt.xlim(xmin = 0)
plt.ylim(ymin = 0)
plt.ylabel("flight level")
plt.xlabel("distance / m");
../_images/1a4054c0551ac44969a5708fa92df8fdf339c283de002a4b4459bc3b132bb71f.png
Hide code cell source
def ec_time_at_lat(ec_track, lat):
    e = np.datetime64("2024-08-01")
    s = np.timedelta64(1, "ns")
    return (((ec_track.swap_dims({"time":"lat"}).time - e) / s).interp(lat=lat) * s + e)
    
plan = path.isel(distance = path.waypoint_indices).to_dataframe().set_index("waypoint_labels")

notes = {'c_south_in':'enter from south, CCW',
         'c_mid_in':'enter from south, CCW',
         'c_north_in':'enter from south, CCW',
         'c_atr_in':'enter from west, CCW',
         'ec_under':f'overpass at {str(ec_time_at_lat(ec_track, ec_under.lat).values)[:-10]}Z',
         }

print (f"Flight: {flight_index}\n")
for index, row in plan.iterrows():
    print(f"{index:15s} {LatLon(row['lat'],row['lon']).format_pilot():20s}, FL{int(row['fl']):03d}, {row['time']:%H:%M:%S}, {notes.get(index,'')}" )

extra_waypoints = [ec_south_alt]

print ('\nextra waypoints:')
for wp in extra_waypoints:
    print (f'{wp.label:15s} {wp.format_pilot()}')
Flight: HALO-20240825a

SAL             N16 44.07, W022 56.64, FL000, 09:15:00, 
north_ec_in     N12 00.00, W031 04.72, FL400, 10:42:09, 
c_north         N10 00.00, W031 27.63, FL400, 10:58:14, 
c_mid           N07 00.03, W032 01.71, FL400, 11:22:22, 
c_south         N04 00.00, W032 35.37, FL400, 11:46:30, 
south_ec        N02 30.00, W032 52.16, FL430, 11:58:28, 
c_south_alt_s   N03 15.00, W032 43.77, FL430, 12:04:25, 
c_south_in      N02 50.67, W032 48.31, FL430, 12:07:38, enter from south, CCW
c_south_out     N02 50.67, W032 48.31, FL430, 13:05:10, 
c_south_alt_n   N04 45.00, W032 26.96, FL430, 13:20:17, 
c_mid_in        N05 50.71, W032 14.70, FL430, 13:28:57, enter from south, CCW
c_mid_out       N05 50.71, W032 14.70, FL430, 14:26:30, 
c_north_alt_s   N09 15.00, W031 36.17, FL430, 14:53:29, 
c_north_in      N08 50.70, W031 40.76, FL450, 14:56:41, enter from south, CCW
c_north_out     N08 50.70, W031 40.76, FL450, 15:53:46, 
c_north_alt_n   N10 45.00, W031 19.06, FL450, 16:08:45, 
ec_under        N13 00.06, W030 53.17, FL450, 16:26:28, overpass at 2024-08-25T16:11:39Z
north_ec_out    N16 00.00, W030 18.17, FL450, 16:50:04, 
MINDELO         N16 52.67, W024 59.70, FL450, 17:30:16, 
atr_sar_in      N15 46.96, W022 41.04, FL350, 17:49:58, 
atr_sar_out     N15 46.96, W022 41.04, FL350, 18:22:26, 
SAL             N16 44.07, W022 56.64, FL000, 18:31:55, 

extra waypoints:
south_ec_alt    N02 00.00, W032 57.76
Hide code cell source
from orcestra.flightplan import export_flightplan

export_flightplan("HALO-20240825a", path)