Flight plan - HALO-20240914a

Contents

Flight plan - HALO-20240914a#

ec_under ec_track c_north c_mid c_south

Crew#

The flight is planned to take off at 2024-09-14 11:50:00+00:00.

Job

Name

PI

Helene Glöckner

WALES

Georgios Dekoutsidis

HAMP

Clara Bayley

Dropsondes

Theresa Mieslinger

Smart/VELOX

André Ehrlich

SpecMACS

Anna Weber

Flight Documentation

Lukas Kluft

Ground contact

Wei-Ting Hsiao

Flight plan#

Hide code cell source
from dataclasses import asdict
from datetime import datetime
import orcestra.sat
from orcestra.flightplan import bco, sal, mindelo, point_on_track, LatLon, IntoCircle, FlightPlan



airport = bco

radius = 72e3*1.852

# Define dates for flight

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

# Load satellite tracks 

ec_fcst_time  = "2024-09-12"
ec_track = orcestra.sat.SattrackLoader("EARTHCARE", ec_fcst_time, kind="PRE",roi="BARBADOS") \
    .get_track_for_day(f"{flight_time:%Y-%m-%d}")\
    .sel(time=slice(f"{flight_time:%Y-%m-%d} 14:00", None))

# Create elements of track
ec_south =  point_on_track(ec_track,lat=  5.0).assign(label = "ec_south")

# circle centers
c_south  = point_on_track(ec_track,lat=  6.75).assign(label = "c_south")
c_mid    = point_on_track(ec_track,lat= 9.7).assign(label = "c_mid")
c_south2  = c_south.towards(c_mid, distance=radius).assign(label="c_south2")
c_north  = point_on_track(ec_track,lat= 12.75).assign(label = "c_north")
#circle in / out (not necessary but nice to have for more waypoints
cn_out    = c_north.towards(c_mid,distance=radius).assign(label = "cn_out")
cm_out = c_mid.towards(c_south, distance=radius).assign(label="cm_out")
cs2_out = c_south2.towards(c_south, distance=radius).assign(label="cs2_out")
cs_out = c_south.towards(c_mid, distance=radius).assign(label="cs_out")
# earthcare end points 
ec_north = c_north.towards(c_mid, distance=radius).assign(label = "ec_north") 

c_wait   = c_south.towards(c_mid, distance=radius*0.5).assign(label = "c_wait")
cw_out = c_south.towards(c_mid, distance=radius*0.9).assign(label = "cw_out")

dir_opt = LatLon(lon=-54.7366666666667, lat=9.23666666666667).assign(label="wp1")#LatLon(lat=7 , lon= -54)
add_wp = LatLon(lon=-54,lat=8.6183).assign(label="wp2")#dir_opt.towards(c_south, fraction=0.6)

# intersection
int_ss1, int_ss2 = IntoCircle(c_south, radius, 360).get_intersect(IntoCircle(c_south2, radius, 360))
int_sm1, int_sm2 = IntoCircle(c_south2, radius, 360).get_intersect(IntoCircle(c_mid, radius, 360))

xlat     = c_mid.towards(cn_out, fraction=1/6).lat
ec_under = point_on_track(ec_track, lat=xlat, with_time=True).assign(label = "ec_under", note = "meet EarthCARE")

# Additional Waypoints

extra_waypoints = []

# Define Flight Paths

waypoints = [
    airport.assign(fl=0),
    #ec_south.assign(fl=410),
    dir_opt.assign(fl=410),
    add_wp.assign(fl=410),
    int_ss2.assign(fl=410, label="scs2_inter"),
    IntoCircle(c_south.assign(fl=410), radius, angle=-360),
    cw_out.assign(fl=430),
    IntoCircle(c_wait.assign(fl=430), radius*0.4, angle=360),
    int_ss1.assign(fl=430, label="scs1_inter"),
    IntoCircle(c_south2.assign(fl=430, label='c_south2'), radius, 360), 
    int_sm1.assign(fl=450, label="scm_inter"),
    IntoCircle(c_mid.assign(fl=450), radius, 360), 
    cm_out.assign(fl=450),
    ec_under.assign(fl=450),
    IntoCircle(c_north.assign(fl=450), radius, angle=360), 
    cn_out.assign(fl=450),
    airport.assign(fl=0),
]

# Crew

crew = {
    'Mission PI': 'Helene Glöckner',
    'DropSondes': 'Theresa Mieslinger',
    'HAMP': 'Clara Bayley',
    'SMART/VELOX': 'André Ehrlich',
    'SpecMACS': 'Anna Weber',
    'WALES' : 'Georgios Dekoutsidis',
    'Flight Documentation': 'Lukas Kluft',
    'Ground Support': 'Wei-Ting Hsiao'
}

# Plan

plan = FlightPlan(waypoints, flight_index, extra_waypoints=extra_waypoints, crew=crew, aircraft="HALO")
print(f"Flight index: {plan.flight_id}")
print(f"Take-off: {plan.takeoff_time:%H:%M %Z}\nLanding:  {plan.landing_time:%H:%M %Z}\n")

print(plan.landing_time - plan.takeoff_time)
Flight index: HALO-20240914a
Take-off: 11:50 UTC
Landing:  20:07 UTC

8:17:37.413849
Hide code cell source
'''

 0732N05125W
 0645N05029W
 0749N05017W
 0721N05023W 
 0709N04921W  0756N05016W 
 0840N04918W/N0430F450 
 0942N04956W  0831N05010W 
 1001N04953W  1245N04921W
 1134N04935W 
 

c_south N06 45.00, W050 29.49, FL410
c_wait N07 20.55, W050 22.82, FL430
c_south2 N07 56.10, W050 16.13, FL430
c_mid N09 42.00, W049 56.08, FL450
c_north N12 45.00, W049 21.11, FL450

N10 00.66, W049 52.53, FL450, 17:25:37 UTC
'''

fx_waypoints = [
    LatLon(lat=7.5333333333333333, lon=-51.4166666666666667 ),
    LatLon(lat=6.75, lon=-50.48333333333333334),
    LatLon(lat=7.8166666666666667, lon=-50.2833333333333333 ),
    LatLon(lat=7.35, lon=-50.38333333333333336 ),
    LatLon(lat=7.15, lon=-49.35),
    LatLon(lat=7.9333333333333333, lon=-50.26666666666666666),
    LatLon(lat=8.6666666666666666, lon=-49.3 ),
    LatLon(lat=9.7, lon=-49.9333333333333333 ),
    LatLon(lat=8.5166666666666667, lon=-50.16666666666666666),
    LatLon(lat=10.016666666666666666, lon=-49.8833333333333333),
    LatLon(lat=12.75, lon=-49.35 ),
    LatLon(lat=11.5666666666666667, lon=-49.5833333333333334 ),
    LatLon(lon=-54.7366666666667, lat=9.23666666666667),
    LatLon(lon=-54,lat=8.6183),
]


fx_south = LatLon(lat=06.75, lon=-50.4915).assign(fl=410)
fx_wait = LatLon(lat=7.3425, lon= -50.38033333333333336).assign(fl=430)
fx_south2 =  LatLon(lat=7.935, lon=-50.2688333333333333).assign(fl=430)
fx_mid = LatLon(lat=9.7, lon= -49.9346666666666666).assign(fl=450)
fx_north = LatLon(lat=12.75, lon=-49.35183333333333333).assign(fl=450)
fx_earth = LatLon(lat=10.011000000000000001, lon=-49.8755000000000001).assign(fl=450)

fx_data = [fx_south, fx_wait, fx_south2, fx_mid, fx_north] + fx_waypoints
Hide code cell source
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import easygems.healpix as egh
import intake
from orcestra.flightplan import plot_cwv, plot_path
import topojson
import json

forecast_overlay=True
# Some fixed coordinates

lon_min, lon_max, lat_min, lat_max = -62, -40, 0, 17

plt.figure(figsize = (14, 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)

if (forecast_overlay):
    ifs_fcst_time = datetime(2024, 9, 13, 0, 0, 0)
    ds = intake.open_catalog("https://tcodata.mpimet.mpg.de/internal.yaml").HIFS(datetime = ifs_fcst_time).to_dask().pipe(egh.attach_coords)
    cwv_flight_time = ds["tcwv"].sel(time=flight_time, method = "nearest")
    plot_cwv(cwv_flight_time, levels = [48.0, 50.0,55.0, 60.0], ax=ax)
    plt.title(f"{flight_time}\n(CWV forecast issued on {ifs_fcst_time})")

plt.plot(ec_track.lon, ec_track.lat, c='k', ls='dotted')
plot_path(plan, ax, color="C1")

with open("worldfirs.json", 'r') as f:
    data = json.load(f)
# parse topojson file using `object_name`
topo = topojson.Topology(data, object_name="data")
firs = topo.to_gdf()
for i, row in firs.iterrows():
    for geom in getattr(row.geometry.boundary, "geoms", [row.geometry.boundary]):
        lon, lat = zip(*list(geom.coords))
        ax.plot(lon, lat, transform=ccrs.PlateCarree(), color='k', lw=1)

for fx in fx_data:
    plt.scatter(fx.lon, fx.lat, c='green', marker='x')
/home/runner/miniconda3/envs/orcestra_book/lib/python3.12/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_physical/ne_50m_coastline.zip
  warnings.warn(f'Downloading: {url}', DownloadWarning)
../_images/aa322f30914ad1989cfdad3a882dfcfa2e4250e2c8e8996bd8166d863e7f818a.png
Hide code cell source
from orcestra.flightplan import vertical_preview

vertical_preview(waypoints)
../_images/b690261d458c53e9adc97aa6ba76176cc85e1c25dd3ba67facad71d5d90da637.png
Hide code cell source
plan.show_details()
plan.export()
Detailed Overview:
              BCO          N13 04.79, W059 29.26, FL000, 11:50:03 UTC, 
to            wp1          N09 14.20, W054 44.20, FL410, 12:47:03 UTC, 
to            wp2          N08 37.10, W054 00.00, FL410, 12:54:35 UTC, 
to            scs2_inter   N07 32.03, W051 24.07, FL410, 13:16:40 UTC, 
circle around c_south      N06 45.00, W050 29.04, FL410, 13:16:40 UTC - 14:16:14 UTC, radius: 72 nm, 360° CCW, enter from north west
to            cw_out       N07 48.99, W050 17.02, FL430, 14:25:14 UTC, 
circle around c_wait       N07 20.55, W050 22.37, FL430, 14:25:14 UTC - 14:48:50 UTC, radius: 29 nm, 360° CW, enter from north
to            scs1_inter   N07 08.93, W049 20.71, FL430, 14:57:48 UTC, 
circle around c_south2     N07 56.10, W050 15.68, FL430, 14:57:48 UTC - 15:56:49 UTC, radius: 72 nm, 360° CW, enter from south east
to            scm_inter    N08 40.07, W049 18.00, FL450, 16:08:37 UTC, 
circle around c_mid        N09 42.00, W049 55.63, FL450, 16:08:37 UTC - 17:07:09 UTC, radius: 72 nm, 360° CW, enter from south east
to            cm_out       N08 30.91, W050 09.11, FL450, 17:13:49 UTC, 
to            ec_under     N10 00.66, W049 52.08, FL450, 17:25:35 UTC, meet EarthCARE
circle around c_north      N12 45.00, W049 20.66, FL450, 17:37:49 UTC - 18:36:21 UTC, radius: 72 nm, 360° CW, enter from south
to            cn_out       N11 33.94, W049 34.33, FL450, 18:36:22 UTC, 
to            BCO          N13 04.79, W059 29.26, FL000, 20:07:41 UTC,