Flight plan - HALO-20240924a#
ec_under ec_track c_west c_east c_pirouetteCrew#
Job |
Name |
---|---|
PI |
Anna Weber |
WALES |
Sabrina Zechlau |
HAMP |
Luca Schmidt |
Dropsondes |
Marius Winkler |
Smart/VELOX |
Kevin Wolf |
SpecMACS |
Tobias Kölling |
Flight Documentation |
Rene Redler |
Ground contact |
Tobias Zinner, Sebastian Ortega |
Flight plan#
from datetime import datetime
import orcestra.sat
from orcestra.flightplan import tbpb, bco, point_on_track, LatLon, IntoCircle, FlightPlan
# Some fixed coordinates
lon_min, lon_max, lat_min, lat_max = -65, -5, -5, 25
airport = tbpb
radius = 72e3*1.852
# Define dates for flight
flight_time = datetime(2024, 9, 24, 12, 0, 0)
flight_index = f"HALO-{flight_time.strftime('%Y%m%d')}a"
# Load satellite tracks
ec_fcst_time = "2024-09-24"
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))
# Use PACE_loader once only
pace_track = orcestra.sat.pace_track_loader() \
.get_track_for_day(f"{flight_time:%Y-%m-%d}")
pace_track = pace_track.where(
(pace_track.lat >lat_min)&
(pace_track.lat <lat_max)&
(pace_track.lon >-60)&
(pace_track.lon <-30),
drop = True) \
.sel(time=slice(f"{flight_time:%Y-%m-%d} 11:00", f"{flight_time:%Y-%m-%d} 21:00"))
Show code cell source
# Create elements of track
c_west_in = LatLon(12.2,-56.0).assign(label = "c_west_in")
c_east_out = LatLon(11,-50).assign(label = "c_east_out")
c_west = c_west_in.towards(c_east_out, distance = radius).assign(label = "c_west")
c_east = c_west.towards(c_east_out, distance = 2*radius+radius).assign(label = "c_east")
ec_north = point_on_track(ec_track,lat= 14.00).assign(label = "ec_north")
ec_south = point_on_track(ec_track,lat= 10.).assign(label = "ec_south")
ec_under = point_on_track(ec_track, lat= 12.0, with_time=True).assign(label = "ec_under", note = "meet EarthCARE")
c_pirouette = (c_west.towards(c_east_out, distance = radius)).towards(ec_north, fraction = 0.5).assign(label = "c_pirouette")
ferry = ec_out = ec_under.assign(time=None, note=None)
# Define Flight Paths
waypoints = [
airport.assign(fl=0),
ferry.assign(fl=390),
c_west_in.assign(fl = 410),
IntoCircle(c_west.assign(fl=410), radius, -360),
ec_south.assign(fl=430),
ec_under.assign(fl=430),
ec_north.assign(fl=430),
ec_out.assign(fl=450),
c_west_in.assign(fl = 450),
IntoCircle(c_west.assign(fl=450), radius, -360),
IntoCircle(c_west.assign(fl=450), radius, -360),
ferry.assign(fl=450, time=None),
airport.assign(fl=0),
]
# Crew
crew = {'Mission PI': 'Anna Weber',
'DropSondes': 'Marius Winkler',
'HAMP': 'Luca Schmidt',
'SMART/VELOX': 'Kevin Wolf',
'SpecMACS': 'Tobias Kölling',
'WALES' : 'Sabrina Zechlau',
'Flight Documentation': 'Rene Redler',
'Ground Support': 'Tobias Zinner, Sebastian Ortega',
}
# Plan
plan = FlightPlan(waypoints, flight_index, 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(f"Duration: {plan.duration}\n")
Flight index: HALO-20240924a
Take-off: 15:41 UTC
Landing: 21:27 UTC
Duration: 5:46:12.073628
Show 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
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, 23, 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, 52.0, 54.0, 56.0, 58.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')
plt.scatter(pace_track.lon, pace_track.lat, s=10, color='darkgreen')
plt.fill_betweenx(pace_track.lat, pace_track.lon,pace_track.lon+1,color='limegreen',alpha=0.2)
plt.fill_betweenx(pace_track.lat, pace_track.lon,pace_track.lon-1,color='limegreen',alpha=0.2)
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)
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, 15:41:44 UTC,
to ec_under N12 00.00, W058 58.56, FL390, 15:52:59 UTC,
to c_west_in N12 12.00, W056 00.00, FL410, 16:16:12 UTC,
circle around c_west N11 58.23, W054 47.86, FL410, 16:16:12 UTC - 17:15:46 UTC, radius: 72 nm, 360° CCW, enter from west
to ec_south N10 00.00, W059 21.47, FL430, 17:46:55 UTC,
to ec_under N12 00.00, W058 58.56, FL430, 18:02:47 UTC, meet EarthCARE
to ec_north N14 00.00, W058 35.42, FL430, 18:18:39 UTC,
to ec_under N12 00.00, W058 58.56, FL450, 18:34:27 UTC,
to c_west_in N12 12.00, W056 00.00, FL450, 18:57:09 UTC,
circle around c_west N11 58.23, W054 47.86, FL450, 18:57:09 UTC - 19:55:42 UTC, radius: 72 nm, 360° CCW, enter from west
circle around c_west N11 58.23, W054 47.86, FL450, 19:55:42 UTC - 20:54:14 UTC, radius: 72 nm, 360° CCW, enter from west
to ec_under N12 00.00, W058 58.56, FL450, 21:16:56 UTC,
to TBPB N13 04.48, W059 29.55, FL000, 21:27:56 UTC,