Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
junzis
GitHub Repository: junzis/openap
Path: blob/master/scripts/extract.py
592 views
1
# %%
2
import warnings
3
from glob import glob
4
5
import click
6
from acropole import FuelEstimator
7
from tqdm.autonotebook import tqdm
8
from traffic.core import Flight, Traffic
9
10
import numpy as np
11
import openap
12
import pandas as pd
13
14
# %%
15
acropole_aircraft = pd.read_csv("acropole_aircraft_params.csv")
16
17
fe = FuelEstimator()
18
19
# %%
20
21
22
def get_flights(typecode, folder, number):
23
aac = acropole_aircraft.query(f"ACFT_ICAO_TYPE=='{typecode.upper()}'")
24
if aac.shape[0] == 0:
25
warnings.warn(f"{typecode} not in acropole")
26
return None
27
28
engine_type = aac.ENGINE_ICAO.iloc[0]
29
30
print(typecode, engine_type)
31
32
files = np.random.permutation(glob(f"{folder}/*.parquet"))
33
34
t_extracted = None
35
36
for i, f in tqdm(
37
enumerate(files), desc=f"reading parquet files to get {number} flights"
38
):
39
t = Traffic.from_file(f)
40
41
if t_extracted is not None:
42
t_extracted = t.query(f"typecode=='{typecode.lower()}'") + t_extracted
43
else:
44
t_extracted = t.query(f"typecode=='{typecode.lower()}'")
45
46
if t_extracted is not None and len(t_extracted.flight_ids) > number:
47
# more than enough flights, randomly sample
48
t_extracted = t_extracted.sample(number)
49
break
50
51
if t_extracted is None and i > 1:
52
# type not found in day one
53
break
54
55
if t_extracted is None:
56
warnings.warn(f"{typecode} no flight data available")
57
return None
58
59
results = []
60
61
for flight in tqdm(t_extracted):
62
df = flight.resample("4s").data.assign(
63
typecode=typecode.upper(),
64
second=lambda d: (d.timestamp - d.timestamp.iloc[0]).dt.total_seconds(),
65
v=lambda d: d.groundspeed * openap.aero.kts,
66
trk=lambda d: np.radians(d.track),
67
vgx=lambda d: d.v * np.sin(d.trk),
68
vgy=lambda d: d.v * np.cos(d.trk),
69
vax=lambda d: d.vgx - d.u_component_of_wind,
70
vay=lambda d: d.vgy - d.v_component_of_wind,
71
tas=lambda d: np.sqrt(d.vax**2 + d.vay**2) / openap.aero.kts,
72
)
73
74
df = fe.estimate(
75
df,
76
second="second",
77
airspeed="tas",
78
)
79
80
results.append(df)
81
82
return pd.concat(results, ignore_index=True)
83
84
85
@click.command()
86
@click.option("--typecode", required=True, help="typecode to extract")
87
@click.option("--folder", required=True, help="path to the input parquet files")
88
@click.option("--number", required=True, type=int, help="Number of flights to extract")
89
def main(typecode, folder, number):
90
flights = get_flights(typecode, folder, number)
91
flights.to_parquet(f"{typecode}_{number}.parquet", index=False)
92
93
94
if __name__ == "__main__":
95
main()
96
97