Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master-v1.5.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
christophe-david committed Sep 4, 2023
2 parents 3fb78ec + ccdd7ba commit db314cd
Show file tree
Hide file tree
Showing 11 changed files with 575 additions and 43 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
Changelog
=========

Version 1.5.2
=============
- Added:
- Added sphinx documentation for source data file generation. (#500)

- Fixed:
- Fix for climb segment going far too high when asked for optimal altitude in some cases. (#497 and #498)
- Now accepting upper case distribution names for FAST-OAD plugins. (#499)
- Now DataFile.from_problem() returns a DataFile instance, and not a VariableList instance. (#494)

Version 1.5.1
=============
- Fixed:
Expand Down
26 changes: 16 additions & 10 deletions docs/documentation/custom_modules/add_plugin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ you may want to share them with other users, which can be done in two ways:
- Packaging your code as a FAST-OAD plugin and have them install it through :code:`pip`
or equivalent. This is the subject of current chapter.

A FAST-OAD plugin can provide additional FAST-OAD modules, Jupyter notebooks and configuration files:
A FAST-OAD plugin can provide additional FAST-OAD modules, Jupyter notebooks, configuration files and source data files:

- plugin-provided FAST-OAD modules are usable in :ref:`configuration files <configuration-file>`,
and can be :ref:`listed<get-module-list>` and :ref:`used<configuration-file-problem-definition>`
in the same way as native modules.
- Command line can be used by users to retrieve :ref:`notebooks<python-usage>` and
:ref:`configuration files<generate-conf-file>`.
- Command line can be used by users to retrieve :ref:`notebooks<python-usage>`,
:ref:`configuration files<generate-conf-file>` and :ref:`source data files<generate-source-data_file>`.

Plugin structure
################
Expand All @@ -36,13 +36,18 @@ In your source folder, a typical plugin structure would be like this::
│ └── some_subpackage/
│ ├── __init__.py
│ └── some_more_code.py
└── notebooks/
├── notebooks/
│ ├── __init__.py
│ ├── any_data/
│ │ ├── __init__.py
│ │ └── some_data.xml
│ ├── awesome_notebook.ipynb
│ └── good_notebook.ipynb
└── source_data_files
├── __init__.py
├── any_data/
│ ├── __init__.py
│ └── some_data.xml
├── awesome_notebook.ipynb
└── good_notebook.ipynb
├── source_data_file_1.xml
├── source_data_file_2.xml
└── source_data_file_3.xml

As shown above, the expected structure is composed of Python **packages**, i.e. every folder should
contain a :code:`__init__.py` file, **even if it contains only non-Python files** (e.g. data for notebooks).
Expand All @@ -58,6 +63,7 @@ Expected folders in a plugin package are:
or API method :meth:`~fastoad.cmd.api.generate_configuration_file`.
- :code:`notebooks`: contains any number of Jupyter notebooks and associated data, that will
be made available to users through :ref:`command line<python-usage>`.
- :code:`source_data_files`: contains only source data files in XML format. As for the :code:`configurations` package, no sub-folder is allowed. These source data files will be usable through :ref:`command line<generate-source-data_file>` or API method :meth:`~fastoad.cmd.api.generate_source_data_file`.

Any of these folders is optional. Any other folder will be ignored.

Expand Down Expand Up @@ -104,7 +110,7 @@ that your project structure contains::
└── ...

As previously stated, your folder :code:`src/star_trek/drives` does not have to contain all of the
folders :code:`models`, :code:`configurations` nor :code:`notebooks`.
folders :code:`models`, :code:`configurations`, :code:`notebooks` nor :code:`source_data_files`.

Assuming you project contains the package :code:`star_trek.drives` that contains
models you want to share, you can declare your plugin in your :code:`pyproject.toml`
Expand Down
17 changes: 16 additions & 1 deletion docs/documentation/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,23 @@ your new input files with:
$ fastoad gen_inputs my_conf.yml my_ref_values.xml
If you are using the configuration file provided by the gen_conf sub-command (see :ref`Generate conf file`), you may download our `CeRAS01_baseline.xml <https://github.com/fast-aircraft-design/FAST-OAD/raw/v0.1a/src/fastoad/notebooks/tutorial/data/CeRAS01_baseline.xml>`_ and use it as source for generating your input file.
If you are using the configuration file provided by the gen_conf sub-command (see :ref:`generate-conf-file`), you may download our `CeRAS01_baseline.xml <https://github.com/fast-aircraft-design/FAST-OAD/raw/v0.1a/src/fastoad/notebooks/tutorial/data/CeRAS01_baseline.xml>`_ and use it as source for generating your input file. You may also generate a source data file using the appropriate command (see :ref:`generate-source-data_file`)

.. _generate-source-data_file:

How to generate a source data file
==================================

As for the configuration file, FAST-OAD can provide a source data file usable for the generation of your input file.

.. code:: shell-session
$ fastoad gen_source_data_file my_source_data_file.xml --from_package my_plugin_package --source sample_source_data_file_1.xml
This copies the file :code:`sample_source_data_file_1.xml` provided by installed package
:code:`my_plugin_package` to file :code:`my_source_data_file.xml`.

The remarks made in section :ref:`how to generate a configuration file<generate-conf-file>` on options :code:`--from_package` and :code:`--source` remain valid when generating a source data file.

.. _view-problem:

Expand Down
5 changes: 3 additions & 2 deletions src/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Basic settings for tests
"""
# This file is part of FAST-OAD : A framework for rapid Overall Aircraft Design
# Copyright (C) 2022 ONERA & ISAE-SUPAERO
# Copyright (C) 2023 ONERA & ISAE-SUPAERO
# FAST is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
Expand Down Expand Up @@ -246,7 +246,8 @@ def with_dummy_plugins():
"""
_setup()
dummy_dist_1 = Mock(importlib_metadata.Distribution)
dummy_dist_1.name = "dummy-dist-1"
# Here we intentionally use an unconventional name (upper case, with underscore)
dummy_dist_1.name = "DUMMY_DIST-1"
dummy_dist_2 = Mock(importlib_metadata.Distribution)
dummy_dist_2.name = "dummy-dist-2"
dummy_dist_3 = Mock(importlib_metadata.Distribution)
Expand Down
63 changes: 63 additions & 0 deletions src/fastoad/_utils/dicts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""
Module for dict-related operations
"""
# This file is part of FAST-OAD : A framework for rapid Overall Aircraft Design
# Copyright (C) 2023 ONERA & ISAE-SUPAERO
# FAST is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

from abc import ABC, abstractmethod
from typing import Any, Iterable, Mapping, TypeVar


_KT = TypeVar("_KT", bound=Any)
_VT = TypeVar("_VT", bound=Any)


class AbstractNormalizedDict(ABC, dict):
"""
Dictionary where keys are normalized using :meth:`normalize`.
Example::
>>> class DictWithLowerCaseKeys(AbstractNormalizedDict):
>>> @staticmethod
>>> def normalize(key):
>>> return key.lower()
"""

@abstractmethod
def normalize(self, key):
"""Redefine this function when subclassing to define your key normalization."""
return key

def __init__(self, seq=None, **kwargs):
kwargs = {self.normalize(key): value for key, value in kwargs.items()}
if seq:
if isinstance(seq, Mapping):
seq = {self.normalize(key): value for key, value in seq.items()}
elif isinstance(seq, Iterable):
seq = [(self.normalize(key), value) for key, value in seq]
super().__init__(seq, **kwargs)
else:
super().__init__(**kwargs)

def __getitem__(self, __key: str) -> _VT:
return super().__getitem__(self.normalize(__key))

def __setitem__(self, __key: str, __value: _VT) -> None:
super().__setitem__(self.normalize(__key), __value)

def __delitem__(self, __key: _KT) -> None:
super().__delitem__(self.normalize(__key))

def __contains__(self, __o: object) -> bool:
return super().__contains__(self.normalize(__o))
45 changes: 45 additions & 0 deletions src/fastoad/_utils/tests/test_dicts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This file is part of FAST-OAD : A framework for rapid Overall Aircraft Design
# Copyright (C) 2023 ONERA & ISAE-SUPAERO
# FAST is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

from ..dicts import AbstractNormalizedDict


class DictWithLowerCaseKeys(AbstractNormalizedDict):
@staticmethod
def normalize(key):
return key.lower()


def test_normalized_dict():

for d in [
DictWithLowerCaseKeys({"Aa": "Aa", "bB": "bB"}),
DictWithLowerCaseKeys(Aa="Aa", bB="bB"),
DictWithLowerCaseKeys([("Aa", "Aa"), ("bB", "bB")]),
DictWithLowerCaseKeys([("Aa", "Aa")], bB="bB"),
]:
print(d)

assert list(d.keys()) == ["aa", "bb"]
assert list(d.values()) == ["Aa", "bB"]

d["cC"] = "cC"
assert list(d.keys()) == ["aa", "bb", "cc"]
assert list(d.values()) == ["Aa", "bB", "cC"]

del d["bb"]
assert list(d.keys()) == ["aa", "cc"]
assert list(d.values()) == ["Aa", "cC"]

assert "aa" in d
assert "Aa" in d
6 changes: 4 additions & 2 deletions src/fastoad/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Definition of globally used constants."""
# This file is part of FAST-OAD : A framework for rapid Overall Aircraft Design
# Copyright (C) 2021 ONERA & ISAE-SUPAERO
# Copyright (C) 2023 ONERA & ISAE-SUPAERO
# FAST is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
Expand Down Expand Up @@ -70,11 +70,13 @@ class RangeCategory(Enum):
Definition of lower and upper limits of aircraft range categories, in Nautical Miles.
can be used like::
>>> range_value = 800.
>>> range_value in RangeCategory.SHORT
True
which is equivalent to:
which is equivalent to::
>>> RangeCategory.SHORT.min() <= range_value <= RangeCategory.SHORT.max()
"""

Expand Down

0 comments on commit db314cd

Please sign in to comment.