System configuration

AEIC uses a lot of configuration data loaded from different files. The system configuration system provides a clean way to manage these different configuration items, using models based on Pydantic to validate input data from TOML files or programmatic sources.

File paths

AEIC has a set of built-in data files, but many use cases will require access to additional external files (for aircraft performance data, weather data, mission databases and so on). AEIC can be given access to directories containing additional configuration or data files by adding those directories to the AEIC_PATH environment variable. This is a colon-separated sequence of absolute directory paths (just like the usual Linux PATH variable).

Anywhere that a file path is required in AEIC, AEIC will search through the directories in the AEIC_PATH variable and in the default AEIC data directory. This search process works slightly differently to the Linux PATH variable: leading directories in the file path that you supply to AEIC are included as part of the search. For example, if you set AEIC_PATH to /big/aeic/data and attempt to load a performance model with a path performance/b738-new.toml, then AEIC will load the file /big/aeic/data/performance/b738-new.toml if it exists.

Configuration initialization and access

The AEIC configuration system is accessed via the AEIC.config package. In normal usage, you import both the Config class and the config singleton instance from this module:

from AEIC.config import Config, config

A selected AEIC configuration must then be loaded using the Config.load method. Calling Config.load() without arguments loads the default AEIC configuration (from the file src/AEIC/data/default_config.toml in the AEIC source tree). Individual configuration settings can be overridden by providing either a TOML file (that needs to contain only the options that are modified), or by passing keyword arguments to the Config.load method. For example, here we set the lifecycle_enabled emissions option to false (it defaults to true) and set the LTO input model to “performance_model” (it defaults to “edb”, and you can use a string or the LTOInputMode enum value). All other values are taken from the default configuration that’s included in the AEIC package.

from AEIC.config import Config, LTOInputMode

Config.load(
    emissions=dict(lifecycle_enabled=False),
    lto_input_mode=LTOInputMode.PERFORMANCE_MODEL,
)

The global AEIC system configuration can be accessed via the config proxy object in the AEIC.config package. Attempting to access values in this object before initializing the system configuration will result in an error:

from AEIC.config import Config, config

print(config.path)
# Raises "ValueError: AEIC configuration is not set"

Config.load()

print(config.path)
# Prints the default AEIC data directory, assuming we have not set AEIC_PATH.

Normally, in AEIC code that is doing calculations that relies on configuration values, you will do from AEIC.config import config at the top of your Python file and then use values like config.emissions.lifecycle_enabled, and these will come from whatever the currently loaded configuration is.

Sometimes, for debugging, you may want to get a real Config object for the current configuration, instead of going via the config proxy. You can do this using the Config.get() method.

Configuration uniqueness and immutability

Only one Config object may exist at any time. This prevents accidentally running part of a simulation with one set of configuration data and another part with a different configuration. There should be no cases in code within AEIC where this poses an obstacle. (It does make testing a little more difficult, but this is dealt with in our test setup code.)

The configuration is frozen: it may not be modified it once it is initialized. This is also intended to avoid problems with simulations running with inconsistent configuration settings. (Again, this does mean that some special tricks are needed for modifying configuration data during tests, but it’s worth the small amount of additional effort to have immutable configuration data for non-test use cases.)

In normal use and development of AEIC code, you should not need to do this, but it’s possible to reset the configuration so that you can load a different one using the Config.reset method. This is important for testing and interactive use of the configuration system, but you should not be doing it in “normal” AEIC code!

Main configuration class

class AEIC.config.Config(*, path: list[~pathlib.Path] = <factory>, performance_model_mode: ~AEIC.config.PerformanceInputMode = PerformanceInputMode.PERFORMANCE_MODEL, performance_model: ~pathlib.Path, lto_input_mode: ~AEIC.config.LTOInputMode = LTOInputMode.PERFORMANCE_MODEL, lto_input_file: ~pathlib.Path | None = None, edb_input_file: ~pathlib.Path | None = None, weather: ~AEIC.weather.config.WeatherConfig, emissions: ~AEIC.emissions.config.EmissionsConfig)

Global AEIC configuration settings.

This is a singleton class; only one instance can be created. This instance can then be accessed as AEIC.config.config via the module-level proxy. To use this, create an instance of Config at the start of your program (probably using the load method), then anywhere else in the codebase you can access the configuration simply by doing from AEIC.config import config.

The intention here is to provide a single source of truth for configuration settings that can be accessed throughout AEIC without needing to pass configuration objects around explicitly. Restricting to a single instance of the configuration class helps to avoid inconsistencies in settings during execution of code using AEIC.

data_file_location(f: Path | str) Path

Get the full path to a file within the configured paths.

default_data_file_location(f: Path | str, missing_ok: bool = False) Path

Get the full path to a file within the default data directory.

edb_input_file: Path | None

Path to engine database file (for LTO emissions when using EDB mode).

emissions: EmissionsConfig

Global emissions configuration settings.

file_location(f: Path | str) Path

Get path to a file, checking local and configured paths.

classmethod get() Config

Get the global configuration singleton.

Raises an error if the configuration has not yet been initialized.

classmethod load(config_file: str | Path | None = None, **kwargs) Config

Load configuration from TOML files.

The default_config.toml file included with AEIC is loaded first, and then TOML data from any config_file provided is loaded and overlaid on top. Additional keyword arguments are finally applied on top of the resulting configuration data. This allows users to only specify configuration options that differ from the defaults.

lto_input_file: Path | None

Path to LTO input data file (when using INPUT_FILE mode).

lto_input_mode: LTOInputMode

defaults to performance model data.

Type:

LTO input mode selection

model_config: ClassVar[ConfigDict] = {'frozen': True}

Configuration is frozen after creation.

normalize_search_paths()

Resolve search paths and initialize the global configuration singleton.

path: list[Path]

List of paths to search for data files. If not initialized explicitly, this is taken from the AEIC_PATH environment variable if set, or defaults to the current working directory only.

performance_model: Path

Path to performance model data file.

performance_model_mode: PerformanceInputMode

defaults to performance model data.

Type:

Performance model input mode selection

static reset()

Reset the global configuration singleton.

This is mostly intended for testing purposes, where it can be useful to modify the configuration between or within tests. In most non-test use cases, the intention is to create a single configuration instance at the start of the program and use that instance throughout.

weather: WeatherConfig

Global weather configuration settings.

Individual module configuration classes

class AEIC.emissions.config.EmissionsConfig(*, fuel: str, climb_descent_usage: bool = True, co2_enabled: bool = True, h2o_enabled: bool = True, sox_enabled: bool = True, nox_method: EINOxMethod = EINOxMethod.BFFM2, hc_method: EINOxMethod = EINOxMethod.BFFM2, co_method: EINOxMethod = EINOxMethod.BFFM2, pmvol_method: PMvolMethod = PMvolMethod.FUEL_FLOW, pmnvol_method: PMnvolMethod = PMnvolMethod.MEEM, apu_enabled: bool = True, gse_enabled: bool = True, lifecycle_enabled: bool = True)

Configuration data for emissions module.

DEFAULT_METHOD: ClassVar[EINOxMethod] = 'bffm2'

Default method for NOx, HC, and CO emissions calculations.

apu_enabled: bool

APU emission calculation flag.

climb_descent_usage: bool

Flag controlling flight phases for which emissions are calculated. If true, emissions are calculated for the entire trajectory (takeoff, climb, cruise, descent); if false, emissions are only calculated for cruise and LTO data is used for takeoff, climb and approach.

co2_enabled: bool

CO2 emission calculation flag.

property co_enabled: bool

CO emission calculation flag.

co_method: EINOxMethod

CO emission calculation method.

fuel: str

Fuel used (conventional Jet-A, SAF, etc.).

property fuel_file: str

Fuel file path.

gse_enabled: bool

GSE emission calculation flag.

h2o_enabled: bool

H2O emission calculation flag.

property hc_enabled: bool

HC emission calculation flag.

hc_method: EINOxMethod

HC emission calculation method.

lifecycle_enabled: bool

Lifecycle emission calculation flag.

model_config: ClassVar[ConfigDict] = {'frozen': True}

Configuration is frozen after creation.

property nox_enabled: bool

NOx emission calculation flag.

nox_method: EINOxMethod

NOx emission calculation method.

property pmnvol_enabled: bool

PMnvol emission calculation flag.

pmnvol_method: PMnvolMethod

PMnvol emission calculation method.

property pmvol_enabled: bool

PMvol emission calculation flag.

pmvol_method: PMvolMethod

PMvol emission calculation method.

sox_enabled: bool

SOx emission calculation flag.

class AEIC.weather.config.WeatherConfig(*, use_weather: bool = True, weather_data_dir: Path | None = None)

Configuration settings for weather module.

model_config: ClassVar[ConfigDict] = {'frozen': True}

Configuration is frozen after creation.

use_weather: bool

Whether to use weather data for emissions calculations.

weather_data_dir: Path | None

Directory path for weather data files. (Files should be NetCDF files following ERA5 conventions with names of the form YYYYMMDD.nc.) If None, defaults to the current working directory.