Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/lint_pytest_deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: Testing

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
lint:
name: Ruff (Lint & Style)
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Install Ruff
run: |
python -m pip install --upgrade pip
python -m pip install ruff

# “ruff check .” performs linting;
# “ruff format --check .” verifies Black-style formatting.
- name: Run Ruff
run: |
ruff check .
ruff format --check .

tests:
name: Pytest
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Install project & dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --editable .
python -m pip install pytest

- name: Set AEIC_DATA_DIR
run: echo "AEIC_DATA_DIR=$(pwd)/data" >> "$GITHUB_ENV"

- name: Run Pytest
run: python -m pytest

21 changes: 14 additions & 7 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,27 @@
import os
import sys

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src')))
sys.path.insert(
0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src'))
)

project = 'AEIC'
copyright = '2025, Wyatt Giroux, Prashanth Prakash, Prateek Ranjan, Aditeya Shukla, Raymond Speth'
author = 'Wyatt Giroux, Prashanth Prakash, Prateek Ranjan, Aditeya Shukla, Raymond Speth'
copyright = (
'2025, Wyatt Giroux, Prashanth Prakash, Prateek Ranjan, '
'Aditeya Shukla, Raymond Speth'
)
author = 'Wyatt Giroux, Prashanth Prakash, Prateek Ranjan, Aditeya Shukla,Raymond Speth'
release = '1.0.0a1'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = ['sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.coverage',
'sphinx.ext.napoleon']
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.coverage',
'sphinx.ext.napoleon',
]
autosummary_generate = True

templates_path = ['_templates']
Expand Down
21 changes: 20 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,23 @@ dev = [

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
build-backend = "hatchling.build"

[tool.ruff]
# Use Black-compatible defaults
line-length = 88

# Optionally, choose which rule sets to enable; this is a typical starting point.
# Remove or extend as you like.
lint.select = ["E", "F", "W", "I", "UP"] # pycodestyle, pyflakes, warnings, isort, pyupgrade
lint.ignore = [] # specify ignores here

# If you want Ruff to auto-format with Black style when you run
# ruff format .
# you don't need any extra options—the default formatter already follows Black’s 88-char width.

[tool.black]
line-length = 88

[tool.ruff.format]
quote-style = "preserve" # keep whatever the file already uses, dont change single quotes to double
57 changes: 35 additions & 22 deletions src/AEIC/performance_model.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,39 @@
import os

import numpy as np
import tomllib
import json
import os
from parsers.PTF_reader import parse_PTF
from parsers.OPF_reader import parse_OPF
from parsers.LTO_reader import parseLTO

from BADA.aircraft_parameters import Bada3AircraftParameters
from BADA.model import Bada3JetEngineModel
from parsers.LTO_reader import parseLTO
from parsers.OPF_reader import parse_OPF

# from src.missions.OAG_filter import filter_OAG_schedule
from utils import file_location


class PerformanceModel:
'''Performance model for an aircraft. Contains
fuel flow, airspeed, ROC/ROD, LTO emissions,
and OAG schedule'''
fuel flow, airspeed, ROC/ROD, LTO emissions,
and OAG schedule'''

def __init__(self, config_file="IO/default_config.toml"):
''' Initializes the performance model by reading the configuration,
'''Initializes the performance model by reading the configuration,
loading mission data, and setting up performance and engine models.'''
config_file_loc = file_location(config_file)
self.config = {}
with open(config_file_loc, 'rb') as f:
config_data = tomllib.load(f)
self.config = {k: v for subdict in config_data.values() for k, v in subdict.items()}
self.config = {
k: v for subdict in config_data.values() for k, v in subdict.items()
}

# Get mission data
# self.filter_OAG_schedule = filter_OAG_schedule
mission_file = file_location(
os.path.join(self.config['missions_folder'], self.config['missions_in_file'])
os.path.join(
self.config['missions_folder'], self.config['missions_in_file']
)
)
with open(mission_file, 'rb') as f:
all_missions = tomllib.load(f)
Expand All @@ -38,9 +44,9 @@ def __init__(self, config_file="IO/default_config.toml"):
self.initialize_performance()

def initialize_performance(self):
'''Initializes aircraft performance characteristics from TOML sourcee.
'''Initializes aircraft performance characteristics from TOML sourcee.
Also loads LTO/EDB data and sets up the engine model using BADA3 parameters.'''

self.ac_params = Bada3AircraftParameters()
# If OPF data input
if self.config["performance_model_input"] == "OPF":
Expand Down Expand Up @@ -68,13 +74,15 @@ def initialize_performance(self):
if self.config["LTO_input_mode"] == "input_file":
# Load LTO data
self.LTO_data = parseLTO(self.config['LTO_input_file'])

def read_performance_data(self):
'''Parses the TOML input file containing flight and LTO performance data.
'''Parses the TOML input file containing flight and LTO performance data.
Separates model metadata and prepares the data for table generation.'''

# Read and load TOML data
with open(file_location(self.config["performance_model_input_file"]), "rb") as f:

# Read and load TOML data
with open(
file_location(self.config["performance_model_input_file"]), "rb"
) as f:
data = tomllib.load(f)

self.LTO_data = data['LTO_performance']
Expand All @@ -98,7 +106,8 @@ def create_performance_table(self, data_dict):
cols = data_dict["cols"]
data = data_dict["data"]

# Identify output column (we assume it's the first column or explicitly labeled as fuel flow)
# Identify output column (we assume it's the first column or
# explicitly labeled as fuel flow)
try:
output_col_idx = cols.index("FUEL_FLOW") # Output is fuel flow
except ValueError:
Expand All @@ -107,8 +116,14 @@ def create_performance_table(self, data_dict):
input_col_names = [c for i, c in enumerate(cols) if i != output_col_idx]

# Extract and sort unique values for each input dimension
input_values = {col: sorted(set(row[cols.index(col)] for row in data)) for col in input_col_names}
input_indices = {col: {val: idx for idx, val in enumerate(input_values[col])} for col in input_col_names}
input_values = {
col: sorted(set(row[cols.index(col)] for row in data))
for col in input_col_names
}
input_indices = {
col: {val: idx for idx, val in enumerate(input_values[col])}
for col in input_col_names
}

# Prepare multidimensional shape and index arrays
shape = tuple(len(input_values[col]) for col in input_col_names)
Expand All @@ -131,5 +146,3 @@ def create_performance_table(self, data_dict):
self.performance_table = fuel_flow_array
self.performance_table_cols = [input_values[col] for col in input_col_names]
self.performance_table_colnames = input_col_names # Save for external reference


16 changes: 7 additions & 9 deletions src/AEIC/trajectories/ads-b_trajectory.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import numpy as np
from AEIC.performance_model import PerformanceModel
from AEIC.trajectories.trajectory import Trajectory


class ADSBTrajectory(Trajectory):
'''Model for determining flight trajectories using ADS-B flight data. Can
be optimized using methods defined by Marek Travnik.
'''
def __init__(self, ac_performance:PerformanceModel):

def __init__(self, ac_performance: PerformanceModel):
super().__init__(ac_performance)



def climb(self):
pass



def cruise(self):
pass



def descent(self):
pass
pass
16 changes: 7 additions & 9 deletions src/AEIC/trajectories/dymos_trajectory.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import numpy as np
from AEIC.performance_model import PerformanceModel
from AEIC.trajectories.trajectory import Trajectory


class DymosTrajectory(Trajectory):
'''Model for determining flight trajectories using ADS-B flight data. Can
be optimized using methods defined by Marek Travnik.
'''
def __init__(self, ac_performance:PerformanceModel):

def __init__(self, ac_performance: PerformanceModel):
super().__init__(ac_performance)



def climb(self):
pass



def cruise(self):
pass



def descent(self):
pass
pass
Loading