Flight plan - HALO-20240919a

Contents

Flight plan - HALO-20240919a#

ec_under ec_track c_north c_mid pace_under meteor curtain radar

Crew#

Job

Name

PI

Clara Bayley

WALES

Sabrina Zechlau

HAMP

Raphaela Vogel

Dropsondes

Helene Glöckner

Smart/VELOX

Patrizia Schoch

SpecMACS

Anna Weber

Flight Documentation

Chelsea Nam

Ground contact

Julia Windmiller and Janina Boemeke

Flight plan#

Hide code cell source
# Define HALO flight and crew
from datetime import datetime

aircraft = "HALO"
flight_time = datetime(2024, 9, 19, 10, 40, 0)
flight_id = f"{aircraft}-{flight_time.strftime('%Y%m%d')}a"
crew = {
    'Mission PI': 'Clara Bayley',
    'DropSondes': 'Helene Glöckner',
    'HAMP': 'Raphaela Vogel',
    'SMART/VELOX': 'Patrizia Schoch',
    'SpecMACS': 'Anna Weber',
    'WALES' : 'Sabrina Zechlau',
    'Flight Documentation': 'Chelsea Nam',
    'Ground Support': 'Julia Windmiller'
}
Hide code cell source
# Define some fixed values
import easygems.healpix as egh
import intake
import numpy as np
import orcestra.sat
from orcestra.flightplan import tbpb

airport = tbpb
radius = 72e3*1.852
smaller_radius = 52e3 * 1.852
halo_speed = 238.5 # at FL450 [m/s]

sat_fcst_date = "2024-09-19" # date to get satelite forecast(s) from
ec_time_slice = slice(f"{flight_time:%Y-%m-%d} 17:40", f"{flight_time:%Y-%m-%d} 17:47") # timeslice of forecast(s) to use
pace_time_slice = slice(f"{flight_time:%Y-%m-%d} 16:19", f"{flight_time:%Y-%m-%d} 16:24") # timeslice of forecast(s) to use

ifs_fcst_time = "2024-09-19" # date to get IFS forecast(s) from
ifs_fcst_time = np.datetime64(ifs_fcst_time + "T00:00:00")

# Load satellite tracks
print(f"SATELITE TRACK FORECAST FROM: {sat_fcst_date} FOR FLIGHT DAY: {flight_time:%Y-%m-%d}")
ec_track = orcestra.sat.SattrackLoader("EARTHCARE", sat_fcst_date, kind="PRE", roi="BARBADOS") \
    .get_track_for_day(f"{flight_time:%Y-%m-%d}") \
        .sel(time=ec_time_slice)

pace_track = orcestra.sat.pace_track_loader() \
    .get_track_for_day(f"{flight_time:%Y-%m-%d}") \
        .sel(time=pace_time_slice)

# Load IFS forecast
cat = "https://tcodata.mpimet.mpg.de/internal.yaml"
ifs_ds = intake.open_catalog(cat).HIFS(datetime=ifs_fcst_time).to_dask().pipe(egh.attach_coords)
SATELITE TRACK FORECAST FROM: 2024-09-19 FOR FLIGHT DAY: 2024-09-19
Hide code cell source
# Create the flight plan
from HALO_20240919a_plan import geod_azi, geod_dist, centre_from_tangent
from orcestra.flightplan import LatLon, point_on_track, IntoCircle, FlightPlan

# Create points for flight path
meteor = LatLon(10.65, -49.5).assign(label="meteor")
pace_ec_overlap = LatLon(16.7792, -53.4286).assign(label="pace_ec_cross")

pace_start = point_on_track(pace_track, lat=11.35).assign(label="pace_start")
pace_end = point_on_track(pace_track, lat=pace_ec_overlap.lat).assign(label = "pace_end")
dist5mins = halo_speed * 5 * 60
pace_end_t5mins = pace_end.towards(pace_start, distance=dist5mins)
pace_under = point_on_track(pace_track, lat=pace_end_t5mins.lat, with_time=True).assign(label="pace_under", note="meet PACE")

ec_start = point_on_track(ec_track, lat=pace_ec_overlap.lat-0.025).assign(label = "ec_start")
ec_end = point_on_track(ec_track, lat=11.88).assign(label = "ec_end")
dist15mins = halo_speed * 15 * 60
ec_start_t15mins = ec_start.towards(ec_start, distance=dist15mins)
ec_under = point_on_track(ec_track, lat=ec_start_t15mins.lat).assign(label="ec_under", note="meet EarthCARE")

dist_between_circles = radius * 2.0 / 3.0
dist1 = geod_dist(airport, pace_start) + 3.0 * radius + 2.0 * dist_between_circles
circ_1 = airport.towards(meteor, distance=dist1).assign(label="c1")
circ_3 = centre_from_tangent(meteor, pace_start, radius, 0).assign(label="c3")
circ_2 = circ_1.towards(circ_3, fraction=1/2).assign(label="c2")
p2 = circ_2.towards(circ_3, distance=radius).assign(label="p2")
circ_4 = centre_from_tangent(ec_end, pace_end, radius, 180).assign(label="c4")
circ_5 = circ_3.towards(airport, distance=geod_dist(circ_1, circ_2)).assign(label="c5")

# Define Waypoints
fl1, fl2, fl3 = 410, 430, 450
waypoints = [
    airport.assign(fl=0),
    meteor.assign(fl=fl1),
    IntoCircle(circ_1.assign(fl=fl2), radius,  angle=-360), # anti-clockwise (optional)
    meteor.assign(fl=fl2),
    p2.assign(fl=fl2),
    IntoCircle(circ_2.assign(fl=fl2), radius,  angle=-360), # anti-clockwise (optional)
    IntoCircle(circ_3.assign(fl=fl3), radius,  angle=-360), # ANTI-CLOCKWISE
    pace_start.assign(fl=fl3),
    pace_under.assign(fl=fl3),
    pace_end.assign(fl=fl3),
    IntoCircle(circ_4.assign(fl=fl3), radius,  angle=360), # CLOCKWISE
    ec_start.assign(fl=fl3),
    ec_under.assign(fl=fl3),
    ec_end.assign(fl=fl3),
    IntoCircle(circ_5.assign(fl=fl3), smaller_radius,  angle=-360), # anti-clockwise (optional)
    airport.assign(fl=0),
]

# Additional Waypoints
extra_waypoints = []

# FlightPlan and print short statement
plan = FlightPlan(path=waypoints, flight_id=flight_id, extra_waypoints=extra_waypoints, crew=crew, aircraft=aircraft)

msg = f"Flight ID: {plan.flight_id}\n" \
    + f"Take-off: {plan.takeoff_time:%H:%M %Z}\n" \
    + f"Landing:  {plan.landing_time:%H:%M %Z}\n" \
    + f"Duration: {plan.duration}"
print(msg)
Flight ID: HALO-20240919a
Take-off: 10:33 UTC
Landing:  19:33 UTC
Duration: 9:00:23.715955
Hide code cell source
from HALO_20240919a_plan import plot_flight_plan_satellite_forecast
from orcestra.flightplan import plot_cwv

figsize=(14, 8)
worldfirs_json = "worldfirs.json"
lon_min, lon_max, lat_min, lat_max = -65, -5, -5, 25
domain_lonlat = [lon_min, lon_max, lat_min, lat_max]

def plot_ifs_cwv_forecast(fig, ax, ifs_ds, flight_time, levels=None):
    cwv_flight_time = ifs_ds["tcwv"].sel(time=flight_time, method="nearest")
    plot_cwv(cwv_flight_time, ax=ax, levels=levels)

plot_cwv_kwargs = {
    "flight_time": flight_time,
    "levels": [45, 50, 55, 60]
    }

fig, ax = plot_flight_plan_satellite_forecast(figsize,
                                    flight_time,
                                    plan,
                                    domain_lonlat,
                                    is_ec_track=True,
                                    ec_track=ec_track,
                                    is_pace_track=True,
                                    pace_track=pace_track,
                                    forecast_overlay=True,
                                    ifs_ds=ifs_ds,
                                    ifs_fcst_time=ifs_fcst_time,
                                    forecast_title_label="CWV",
                                    plot_forecast_func=plot_ifs_cwv_forecast,
                                    plot_forecast_kwargs=plot_cwv_kwargs,
                                    atc_zones=True,
                                    worldfirs_json=worldfirs_json,
                                    is_meteor=True,
                                    meteor=meteor)
../_images/246f76731d82cb23531b6f796a9d00c283eb0e62d1b20dcf3d25e4e70f156f3e.png
Hide code cell source
import HALO_20240919a_sfc_winds as sfc_winds

figsize=(16, 9)
worldfirs_json = "worldfirs.json"
lon_min, lon_max, lat_min, lat_max = -65, -5, -5, 25
domain_lonlat = [lon_min, lon_max, lat_min, lat_max]

def plot_ifs_sfc_winds_forecast(fig, ax, ifs_ds, domain_lonlat, flight_time):
    u10m = ifs_ds["10u"].sel(time=flight_time, method="nearest")
    v10m = ifs_ds["10v"].sel(time=flight_time, method="nearest")
    windspeed_10m = np.sqrt(u10m**2 + v10m**2)
    sfc_winds._windspeed_plot(windspeed_10m, fig, ax)
    sfc_winds._wind_direction_plot(u10m, v10m, ax, domain_lonlat)
    sfc_winds._windspeed_contour(windspeed_10m, ax)
    sfc_winds._draw_confluence_contour(v10m, ax)

plot_ifs_sfc_winds_kwargs = {
    "domain_lonlat": domain_lonlat,
    "flight_time": flight_time,
}

fig, ax = plot_flight_plan_satellite_forecast(figsize,
                                    flight_time,
                                    plan,
                                    domain_lonlat,
                                    is_ec_track=True,
                                    ec_track=ec_track,
                                    is_pace_track=True,
                                    pace_track=pace_track,
                                    forecast_overlay=True,
                                    ifs_ds=ifs_ds,
                                    ifs_fcst_time=ifs_fcst_time,
                                    forecast_title_label="10m Winds",
                                    plot_forecast_func=plot_ifs_sfc_winds_forecast,
                                    plot_forecast_kwargs=plot_ifs_sfc_winds_kwargs,
                                    atc_zones=True,
                                    worldfirs_json=worldfirs_json,
                                    is_meteor=True,
                                    meteor=meteor)
../_images/65dc08e81ceee171d682cb3dd322509dff56c6d79f24a23933550cc3f0fe44cc.png
Hide code cell source
from orcestra.flightplan import vertical_preview

vertical_preview(waypoints)
../_images/7c6fc0ab3aa38671fdd300bbbea4efb6b134d7feff7f7799cafb3f38054f1586.png
Hide code cell source
plan.show_details()
plan.export()
Detailed Overview:
              TBPB         N13 04.48, W059 29.55, FL000, 10:33:13 UTC, 
to            meteor       N10 39.00, W049 30.00, FL410, 12:08:29 UTC, 
circle around c1           N10 02.31, W047 12.11, FL430, 12:17:30 UTC - 13:16:31 UTC, radius: 72 nm, 360° CCW, enter from west
to            meteor       N10 39.00, W049 30.00, FL430, 13:25:29 UTC, 
to            p2           N11 09.51, W051 31.44, FL430, 13:41:34 UTC, 
circle around c2           N10 51.54, W050 20.53, FL430, 13:41:34 UTC - 14:40:35 UTC, radius: 72 nm, 360° CCW, enter from west
circle around c3           N11 38.84, W053 29.95, FL450, 14:46:49 UTC - 15:45:22 UTC, radius: 72 nm, 360° CCW, enter from east
to            pace_start   N11 21.00, W052 18.88, FL450, 15:45:25 UTC, 
to            pace_under   N16 08.84, W053 21.84, FL450, 16:23:21 UTC, meet PACE
to            pace_end     N16 46.75, W053 30.28, FL450, 16:28:21 UTC, 
circle around c4           N15 35.51, W053 43.03, FL450, 16:28:21 UTC - 17:26:53 UTC, radius: 72 nm, 360° CW, enter from north
to            ec_start     N16 45.25, W053 26.31, FL450, 17:27:25 UTC, 
to            ec_under     N14 48.86, W053 49.14, FL450, 17:42:42 UTC, meet EarthCARE
to            ec_end       N11 52.80, W054 23.15, FL450, 18:05:47 UTC, 
circle around c5           N12 25.24, W056 40.14, FL450, 18:16:55 UTC - 18:59:12 UTC, radius: 52 nm, 360° CCW, enter from east
to            TBPB         N13 04.48, W059 29.55, FL000, 19:33:37 UTC,