Flight plan - HALO-20240919a#
ec_under ec_track c_north c_mid pace_under meteor curtain radarCrew#
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#
Show 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'
}
Show 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
Show 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
Show 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)
Show 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)
Show code cell source
from orcestra.flightplan import vertical_preview
vertical_preview(waypoints)
Show 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,