Skip to content

Commit

Permalink
refactoring codebase
Browse files Browse the repository at this point in the history
  • Loading branch information
junzis committed May 8, 2024
1 parent 11ba579 commit 00a692c
Show file tree
Hide file tree
Showing 19 changed files with 177 additions and 482 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
tmp/

.DS_Store

# Byte-compiled / optimized / DLL files
Expand Down
1 change: 1 addition & 0 deletions acropole/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .estimator import FuelEstimator
129 changes: 0 additions & 129 deletions acropole/columns.py

This file was deleted.

Empty file removed acropole/data/__init__.py
Empty file.
30 changes: 0 additions & 30 deletions acropole/data/acft_params.csv

This file was deleted.

30 changes: 30 additions & 0 deletions acropole/data/aircraft_params.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
ACFT_ICAO_TYPE,ENGINE_ICAO,PERCENTAGE,FUEL_FLOW_TO,TYPE,WTC,SURFACE,MAX_OPE_ALTI,MAX_OPE_MACH_NUM,MAX_TO_WEIGHT,OPE_EMPTY_WEIGHT,ACFT_SPAN,ACFT_LENGTH,ENGINE_NUM,TRAIN_ON,MAX_OPE_SPEED,CONF_IND,ENGINE_TYPE
A318,CFM56-5B9/3,52.46,0.956,JET,M,122.6,39800.0,0.82,68000.0,40900.0,34.1,31.45,2.0,0,471.51923854894073,0.88,0.0
A319,V2524-A5,20.42,1.042,JET,M,122.6,39800.0,0.82,70000.0,39000.0,34.1,33.84,2.0,0,471.51923854894073,0.875,0.0
A320,CFM56-5B4/P,41.98,1.132,JET,M,122.6,41100.0,0.82,78000.0,43700.0,34.1,37.57,2.0,1,471.51923854894073,1.0,0.0
A321,V2533-A5,57.58,1.426,JET,M,122.6,39800.0,0.82,83000.0,47000.0,34.15,44.5,2.0,0,471.51923854894073,0.884,0.0
A332,Trent 772,77.59,3.15,JET,H,361.6,41500.0,0.86,230000.0,125964.0,60.304,58.372,2.0,1,494.5201770147428,1.0,0.0
A333,Trent 772,79.19,3.15,JET,H,361.6,41100.0,0.86,212000.0,126000.0,60.304,63.689,2.0,0,494.5201770147428,0.891,0.0
A337,Trent 772,100.0,3.15,JET,H,361.6,41100.0,0.86,227000.0,125000.0,60.3,63.1,2.0,0,494.5201770147428,0.89,0.0
A338,Trent7000-72,100.0,2.478,JET,H,361.6,41100.0,0.86,242000.0,129000.0,64.0,58.81,2.0,0,494.5201770147428,0.849,0.0
A339,Trent7000-72,100.0,2.478,JET,H,361.6,41100.0,0.86,251000.0,129000.0,64.0,63.66,2.0,0,494.5201770147428,0.854,0.0
AT72,PW124B-HS14SF,100.0,0.1807,TURBOPROP,M,61.0,25000.0,0.55,21500.0,12300.0,27.05,27.166,2.0,0,331.6003035355095,0.899,1.0
AT73,PW127-HS247F,100.0,0.1877416666599999,TURBOPROP,M,61.0,25000.0,0.55,21500.0,12300.0,27.05,27.166,2.0,0,331.6003035355095,0.899,1.0
AT75,PW127F-HS568F,100.0,0.18969166,TURBOPROP,M,61.0,25000.0,0.55,22000.0,12850.0,27.05,27.166,2.0,0,331.6003035355095,0.9,1.0
AT76,PW127M-HS568F,100.0,0.18969166,TURBOPROP,M,61.0,25000.0,0.55,22800.0,13200.0,27.05,27.166,2.0,1,331.6003035355095,1.0,1.0
B732,JT8D-15A,34.31,1.115,JET,M,91.0449792,37000.0,0.84,52390.0,27125.0,28.35,30.53,2.0,0,483.01970778184176,0.885,0.0
B733,CFM56-3C-1,63.28,1.154,JET,M,91.0449792,37000.0,0.82,61236.0,32904.0,28.88,33.4,2.0,0,471.51923854894073,0.876,0.0
B734,CFM56-3C-1,96.83,1.154,JET,M,91.0449792,37000.0,0.82,68040.0,33190.0,28.88,36.4,2.0,0,471.51923854894073,0.876,0.0
B735,CFM56-3C-1,86.09,1.154,JET,M,91.0449792,37000.0,0.82,60555.0,31312.0,28.88,31.01,2.0,0,471.51923854894073,0.882,0.0
B736,CFM56-7B22,26.92,1.021,JET,M,124.58297664,41000.0,0.82,65544.0,36378.0,34.32,31.24,2.0,0,471.51923854894073,0.879,0.0
B737,CFM56-7B26,19.21,1.221,JET,M,124.58297664,41000.0,0.82,70080.0,37648.0,35.79,33.63,2.0,0,471.51923854894073,0.891,0.0
B738,CFM56-7B26E,38.29,1.213,JET,M,124.58297664,41000.0,0.82,79016.0,41413.0,35.79,39.47,2.0,1,471.51923854894073,1.0,0.0
B739,CFM56-7B27E,38.55,1.293,JET,M,124.58297664,41000.0,0.82,85139.0,44676.0,35.79,42.11,2.0,0,471.51923854894073,0.886,0.0
CRJ7,CF34-8C5B1,94.29,0.606,JET,M,70.6,41000.0,0.78,34019.4,20069.0,23.24,32.51,2.0,1,448.5183000831388,1.0,0.0
CRJ9,CF34-8C5,73.63,0.6481,JET,M,71.1,41000.0,0.78,36514.0,21845.0,24.9,36.19,2.0,0,448.5183000831388,0.886,0.0
CRJX,CF34-8C5A1,100.0,0.665,JET,M,77.4,41000.0,0.78,41640.0,23188.0,26.2,39.1,2.0,1,448.5183000831388,1.0,0.0
E170,CF34-8E5,79.86,0.6518,JET,M,72.72,41000.0,0.82,35990.0,21121.0,26.0,29.9,2.0,1,471.51923854894073,1.0,0.0
E190,CF34-10E5,54.31,0.789,JET,M,92.53,41000.0,0.82,47790.0,27737.0,28.72,36.24,2.0,1,471.51923854894073,1.0,0.0
E195,CF34-10E5A1,41.18,0.866,JET,M,92.53,41000.0,0.82,48790.0,28567.0,28.72,38.67,2.0,0,471.51923854894073,0.888,0.0
E75L,CF34-8E5,100.0,0.6518,JET,M,72.72,41000.0,0.82,38790.0,21870.0,26.0,31.68,2.0,0,471.51923854894073,0.894,0.0
E75S,CF34-8E5,100.0,0.6518,JET,M,72.72,41000.0,0.82,37500.0,21870.0,26.0,31.68,2.0,0,471.51923854894073,0.894,0.0
141 changes: 141 additions & 0 deletions acropole/estimator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import warnings

import numpy as np
import pandas as pd
import pkg_resources
import tensorflow as tf


class FuelEstimator:
"""
Class that contains data pipelines for trajectory enhancement
"""

DEFAULT_MASS = -1.0
MAXIMUMS = np.array([1, 5000, 50, 50, 600, 50000, 800, 50000, 800, 800, 5000, 1])
MINIMUMS = np.array([0, -5000, -50, -50, 0, 0, 200, 0, 200, 200, -5000, 0])

def __init__(self, aircraft_params_path: str = None, model_path: str = None):
"""
Initializes the Trajectory class.
Args:
aircraft_table_path (str): The path to the aircraft table. Default is None (use package data).
model_path (str): The path to the prediction model. Default is None (use package data).
"""

if aircraft_params_path is None:
aircraft_params_path = pkg_resources.resource_filename(
"acropole", "data/aircraft_params.csv"
)

self.aircraft_params = pd.read_csv(aircraft_params_path)

if model_path is None:
model_path = pkg_resources.resource_filename(
"acropole", "models/acropole.keras"
)

self.model = tf.keras.models.load_model(model_path)

def estimate(self, flight: pd.DataFrame, **kwargs) -> pd.DataFrame:
"""
Estimates fuel flow and consumption based on the flight trajectory.
Args:
flight (pd.DataFrame): The flight data as a pandas DataFrame.
**kwargs: Additional keyword arguments for customization.
Keyword Args:
typecode (str): The column name for the aircraft type code. Default is "typecode".
timestamp (str): The column name for the timestamp. Default is "timestamp".
groundspeed (str): The column name for the groundspeed. Default is "groundspeed".
altitude (str): The column name for the altitude. Default is "altitude".
vertical_rate (str): The column name for the vertical rate. Default is "vertical_rate".
airspeed (str): The column name for the airspeed. Default is "airspeed".
mass (str): The column name for the mass. Default is "mass".
Returns:
pd.DataFrame: The flight data with additional estimated fuel parameters.
Raises:
AssertionError: If the 'timestamp' column is not of type float.
Warnings:
If the aircraft type code is not supported.
"""

col_typecode = kwargs.get("typecode", "typecode")
col_timestamp = kwargs.get("timestamp", "timestamp")
col_groundspeed = kwargs.get("groundspeed", "groundspeed")
col_altitude = kwargs.get("altitude", "altitude")
col_vertical_rate = kwargs.get("vertical_rate", "vertical_rate")
col_airspeed = kwargs.get("airspeed", "airspeed")
col_mass = kwargs.get("mass", "mass")

assert (
flight[col_timestamp].dtype == float
), "'timestamp' must be a series of float"

flight_typecode = flight[col_typecode].iloc[0]
if flight_typecode not in self.aircraft_params.ACFT_ICAO_TYPE.unique():
warnings.warn(
f"Aircraft type {flight_typecode} flight_typecode not supported"
)

flight = flight.merge(
self.aircraft_params,
how="left",
left_on=col_typecode,
right_on="ACFT_ICAO_TYPE",
)

if col_airspeed not in flight.columns:
flight = flight.assign(airspeed=lambda d: d[col_groundspeed])

if col_mass not in flight.columns:
flight = flight.assign(mass_norm=self.DEFAULT_MASS)
else:
flight = flight.assign(
mass_norm=lambda d: (d[col_mass] - d.OPE_EMPTY_WEIGHT)
/ (d.MAX_TO_WEIGHT - d.OPE_EMPTY_WEIGHT)
)

# compute devrivatives of altitude and speeds
flight = flight.assign(dt=lambda d: d[col_timestamp].diff().bfill()).assign(
d_altitude=lambda d: (d[col_altitude].diff().bfill() / d.dt),
d_groundspeed=lambda d: (d[col_groundspeed].diff().bfill() / d.dt),
d_airspeed=lambda d: (d[col_airspeed].diff().bfill() / d.dt),
)

inputs = flight[
[
"ENGINE_TYPE",
"d_altitude",
"d_groundspeed",
"d_airspeed",
"SURFACE",
"MAX_OPE_ALTI",
"MAX_OPE_SPEED",
col_altitude,
col_groundspeed,
col_airspeed,
col_vertical_rate,
"mass_norm",
]
]

inputs_normalized = (inputs - self.MINIMUMS) / (self.MAXIMUMS - self.MINIMUMS)
data = tf.convert_to_tensor(inputs_normalized)

single_engine_fuelflow = self.model.predict(data).squeeze()

flight = flight.assign(
fuel_flow=lambda d: single_engine_fuelflow * d.ENGINE_NUM,
fuel_flow_kgh=lambda d: d.fuel_flow * d.FUEL_FLOW_TO * 3600,
fuel_cumsum=lambda d: (d.fuel_flow * d.dt).cumsum(),
)

return flight
Empty file.
Empty file.
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
Empty file removed acropole/models/__init__.py
Empty file.
Binary file added acropole/models/acropole.keras
Binary file not shown.
Loading

0 comments on commit 00a692c

Please sign in to comment.