From 6bab9e7dc51963310545deb58fcd7673db59889b Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Fri, 1 Nov 2024 17:16:42 -0400 Subject: [PATCH 01/57] Initial commit --- .gitignore | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..82f9275 --- /dev/null +++ b/.gitignore @@ -0,0 +1,162 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ From c3e3fae548f275f4bfa9a6dd13f27e2e5f776468 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Fri, 1 Nov 2024 18:50:07 -0400 Subject: [PATCH 02/57] Initial PropLib Python wrapper template --- .gitignore | 4 + .pre-commit-config.yaml | 43 +++ CONTRIBUTING.md | 350 ++++++++++++++++++++ LICENSE.md | 34 ++ pyproject.toml | 65 ++++ src/ITS/PropLibTemplate/__init__.py | 11 + src/ITS/PropLibTemplate/proplib_loader.py | 101 ++++++ src/ITS/PropLibTemplate/proplib_template.py | 19 ++ tests/test_proplib_template.py | 21 ++ tox.ini | 25 ++ 10 files changed, 673 insertions(+) create mode 100644 .pre-commit-config.yaml create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.md create mode 100644 pyproject.toml create mode 100644 src/ITS/PropLibTemplate/__init__.py create mode 100644 src/ITS/PropLibTemplate/proplib_loader.py create mode 100644 src/ITS/PropLibTemplate/proplib_template.py create mode 100644 tests/test_proplib_template.py create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index 82f9275..ac9216b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,10 @@ __pycache__/ # C extensions *.so +*.so.* +*.dylib +*.DLL +*.dll # Distribution / packaging .Python diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..98651e8 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,43 @@ +default_language_version: + python: python3.9 +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: check-ast + types: [file, python] + - id: check-case-conflict + - id: check-docstring-first + types: [file, python] + - id: check-merge-conflict + - id: check-yaml + types: [file, yaml] + - id: debug-statements + types: [file, python] + - id: detect-private-key + - id: end-of-file-fixer + - id: trailing-whitespace + - repo: https://github.com/asottile/pyupgrade + rev: v3.19.0 + hooks: + - id: pyupgrade + args: ["--py39-plus"] + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + name: isort (python) + types: [file, python] + args: ["--profile", "black", "--filter-files", "--gitignore"] + - repo: https://github.com/psf/black + rev: 24.10.0 + hooks: + - id: black + types: [file, python] + - repo: https://github.com/igorshubovych/markdownlint-cli + rev: v0.42.0 + hooks: + - id: markdownlint + types: [file, markdown] + exclude: GitHubRepoPublicReleaseApproval.md + args: ["--disable", "MD013"] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5f75e90 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,350 @@ +# NTIA/ITS Propagation Library Contribution Guide + +Thank you for your interest in contributing to this open source software. On this +page you will get an overview of the contribution workflow from opening an issue, +creating a PR, reviewing, +and merging the PR. This page also includes some information about the project +structures, development workflows, and code styles which are used throughout the +ITS Propagation Library. + +If you are instead interested in usage documentation, please refer to the +[Propagation Library Wiki](https://ntia.github.io/propagation-library-wiki). + +## Contents + +- [Found a Bug?](#found-a-bug) +- [Background for New Contributors](#background-for-new-contributors) +- [Notes on Code Style](#notes-on-code-style) +- [Project Structure and CMake](#project-structure-and-cmake) +- [Documenting Code](#documenting-code) +- [Testing Code](#testing-code) + +## Found a Bug? + +If you spot a problem with this software, +[search if an issue already exists](https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-issues-and-pull-requests#search-by-the-title-body-or-comments). +If a related issue doesn't exist, we encourage you to open one (even if you +don't plan to contribute a resolution yourself). Issues may be opened for bugs, +documentation errors, or feature requests. + +## Background for new contributors + +The workflow we recommend and describe here follows from best and common +practices in the Git and GitHub ecosystems. We aim to leverage this workflow, +especially the elements of code review and approval, to enable open source +development of robust, trustworthy radio propagation software. Here are some +resources to help you get started with open source contributions: + +- [Set up Git](https://docs.github.com/en/get-started/getting-started-with-git/set-up-git) +- [GitHub flow](https://docs.github.com/en/get-started/using-github/github-flow) +- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests) +- [Basic explanation of Git submodules](https://gist.github.com/gitaarik/8735255) +by [**@gitaarik**](https://github.com/gitaarik) + +### Git Branches + +Our repositories use the following approach to organize and keep track of branches. +The `main` branch typically represents the most recently released version of the software. +The `dev` branch stages changes before they are merged into `main` and a new release is created. +New features or bug fixes should be developed on individual "feature branches" with descriptive names. +When complete, features branches should merge into `dev`. + +### Git Submodules + +Software in the ITS Propagation Library is implemented primarily in C++. Each piece +of software has a primary repository which contains the base C++ implementation, +test data and resources, and common files used by the multi-language wrappers. +Interfaces for additional programming languages are provided in separate repositories, +which are linked to the primary repository as [Git submodules](https://gist.github.com/gitaarik/8735255). +When cloning the primary repository, the submodules are not additionally cloned +by default. This can be done with the `git submodule init` command. Initializing +the submodule as part of the parent repository will let you use the build +configuration from the primary repository to compile the C++ source and place it +appropriately for use by the wrapper code. If you choose to independently clone +the wrapper repository, you will likely need to separately download the compiled +library (for example, a DLL from a GitHub release). + +### Contributing on GitHub + +If you'd like to solve an existing issue, add a new feature, or modify this software, +follow these steps when making your changes. + +1. Fork the repository. This allows you to make your changes without affecting the +original project until you're ready to merge them. You can create a fork +[with GitHub Desktop](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/cloning-and-forking-repositories-from-github-desktop) +or [using the command line](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) + +1. Create a working branch and start with your changes! Commit changes +incrementally to your fork. See the sections below for details about unit tests, +code style, and documentation. + +1. When you're done making changes, create a pull request (PR). In your PR, please include +a meaningful description of the changes you've made. If your PR solves an issue, +[link to it](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue)! + +Once you submit your PR, a maintainer will review your changes to determine +whether or not they should be merged. We may ask questions or request additional +changes which must be addressed. For example, we may request changes so that the code +meets structure, formatting, accuracy, or testing requirements. + +If your PR is approved and merged, your changes will be a part of the `dev` +branch of the repository, where they will stay until a new release is made. At that +point, `dev` will merge into `main` and a new release will be created. The maintainers +of a repository hold the authority on when a new release should be created. For example, +important bug fixes may take higher priority, while small improvements may stay on `dev` +for a while. Rest assured, even if a new release is not immediately made, your approved +changes will be always packaged into the next release. + +## Notes on Code Style + +- In general, variables follow the naming convention in which a single underscore +denotes a subscript (pseudo-LaTeX format), where a double underscore is followed +by the units, i.e. `h_1__meter`. +- Variables are named to match their corresponding mathematical variables in the +underlying text, when applicable. +- Wherever possible, equation numbers are provided. It is assumed that a user +reviewing this source code would have a copy of the relevant text available +as a primary reference. +- _For base/C++ repositories_, a `.clang-format` file is included in the root directory. +Most IDEs support this type of file, which can and should be used to apply uniform +code styling to C++ source and header files. +- _For Python wrapper repositories_, a `.pre-commit-config.yaml` file is included +in the root directory. This file implements multiple hooks for the [pre-commit](https://pre-commit.com/) +tool, which apply automated formatting to files when they are committed to Git. +It is recommended to use this tool to autoformat Python code when checked in. + +## Project Structure and CMake + +Software in the ITS Propagation Library is primarily implemented in C++, then +wrapped with interfaces exposing the C++ library to users of other languages. The +primary repository for each software package uses [CMake](https://cmake.org/) to +handle cross-platform C++ build configuration, C++ unit tests (with +[GoogleTest](https://github.com/google/googletest) and +[CTest](https://cmake.org/cmake/help/latest/manual/ctest.1.html)), and generation of +API documentation (with [Doxygen](https://www.doxygen.nl/)). Many IDEs support CMake +integration in some form or fashion, and it is recommended that you familiarize yourself +with any such functionality of your chosen IDE. + +This section shows a typical project structure for a primary (i.e., non-wrapper) +repository. For details about wrapper repositories, refer to their own README files. + +```bash +app/ # The command-line driver which can run the library + data/ # Example input and output files for use with the driver + include/ # Headers used by the command-line driver + src/ # Source code for the command-line driver + tests/ # Header and source files for testing the command-line driver + CMakeLists.txt # Configuration for the command-line driver and its tests + README.md # Usage information for the command-line driver +docs/ + CMakeLists.txt # Doxygen configuration + ... # Static files (images, HTML, CS, Markdown) used by Doxygen +extern/ + ... # External Git submodules/dependencies +include/ + / # Include namespace folder, e.g. "ITS.Propagation.ITM" + .h # Library header files go here, e.g. "ITM.h" and "ErrorCodes.h" +src/ + .cpp # Source files go here, e.g. "LongleyRice.cpp" and "FreeSpaceLoss.cpp" + CMakeLists.txt # Configures cross-platform build +tests/ + data/ + .csv # Testing data goes here. Does not have to be CSV. + .cpp # Unit tests, usually one test file per source file. + .h # Any headers used by tests go here as well. + CMakeLists.txt # CTest+GTest config. Files containing tests must be included here. +wrap/ + dotnet/ # C#/.NET wrapper submodule. Should contain CMakeLists.txt + matlab/ # MATLAB wrapper submodule. Should contain CMakeLists.txt + python/ # Python wrapper submodule. Should contain CMakeLists.txt +CMakeLists.txt # Top-level CMakeLists.txt: project metadata and options +CMakePresets.json # Presets for CMake, e.g. "release", "debug", etc. +... +``` + +### CMake Options and CMake Presets + +As you can see, multiple `CMakeLists.txt` files exist within the project. Each +one contains configurations relevant to the directory where it is stored. For +example, the `tests/CMakeLists.txt` file configures unit tests using CMake. The +top-level `CMakeLists.txt` stores the primary project configuration and includes +the lower-level configurations based on the preset or specified CMake options. + +The following CMake options are used for top-level project configuration: + +| Option | Default | Definition | +|--------------------|---------|------------------------------------------| +| `BUILD_DOCS` | `ON` | Generate documentation site with Doxygen | +| `BUILD_DRIVER` | `ON` | Build the command-line driver executable | +| `RUN_DRIVER_TESTS` | `ON` | Test the command-line driver executable | +| `DOCS_ONLY` | `OFF` | Skip all steps _except_ generating the documentation site | +| `RUN_TESTS` | `ON` | Run unit tests for the main library | +| `COPY_TO_WRAPPERS` | `ON` | Copy the compiled shared library into wrapper submodules | + +[CMake Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) are +provided to support common build configurations. These are specified in the +`CMakePresets.json` file. The `release` preset will compile the library and driver +with optimizations, build the documentation site, and run all unit tests. The `debug` preset +will skip building the documentation site, driver, and driver tests, which can be useful for +rapid development and testing. Additionally, the Debug configuration will attempt to pass +debug flags to the compiler. Finally, the "docsOnly" preset skips all steps except for +generating the Doxygen documentation site. + +| Option | `release` preset | `debug` preset | `docsOnly` preset | +|--------------------|------------------|----------------|-------------------| +| `DOCS_ONLY` | `OFF` | `OFF` | `ON` | +| `RUN_TESTS` | `ON` | `ON` | `OFF` | +| `CMAKE_BUILD_TYPE` | `Release` | `Debug` | not set | +| `BUILD_DOCS` | `ON` | `OFF` | `ON` | +| `BUILD_DRIVER` | `ON` | `OFF` | `OFF` | +| `RUN_DRIVER_TESTS` | `ON` | `OFF` | `OFF` | + +Below are some examples of how CMake can be called to compile this software. + +```bash +# Configure and compile in release configuration +cmake --preset release +cmake --build --preset release + +# Use the release configuration but don't build Doxygen docs +cmake --preset release -DBUILD_DOCS=OFF +cmake --build --preset release + +# Configure and compile in debug configuration +cmake --preset debug +cmake --build --preset debug + +# Use the release configuration but don't run driver tests +cmake --preset release -DRUN_DRIVER_TESTS=OFF +cmake --build --preset release +``` + +### Supported Platforms and Build Options + +The provided `CMakeLists.txt` and `CMakePresets.json` files aim to be flexible +for development from the platform of your choosing. The approach taken is to make +few assumptions about your toolchain to implicitly enable cross-platform and +multi-environment development as much as possible. However, we cannot guarantee +that all compilers, tools, and platforms will work without requiring some additional +configuration which is not documented here. If you find an issue or would like to +see a change to support your chosen platform or tools, open an issue or create a +pull request! + +## Documenting Code + +### C++ Base Libraries + +The C++ source code is documented with Doxygen. A GitHub Action is configured to +build and deploy the documentation using GitHub Pages. This action will ensure +that any new code has been accompanied by Doxygen-formatted documentation. Code +will not be merged until and unless it is completely documented using Doxygen, +and the GitHub action successfully generates the documentation site. Below is an +example showing the expected documentation formats. Except for inline documentation, +use the JavaDoc banner style [described by Doxygen](https://www.doxygen.nl/manual/docblocks.html) + +```cpp +constexpr double = PI 3.1415; /**< Inline format, e.g. for constants */ + +/******************************************************************************* + * This is a brief description of the function. + * + * This is an optional, longer description of the function. It can include + * LaTeX formatting, for example: this function doubles its input @f$ x @f$ and + * returns a value @f$ y @f$ with @f$ y = 2x @f$. This whole documentation block + * is using the JavaDoc banner style! + * + * @param[in] x The input and its expected units + * @return The result @f$ y = 2x @f$ + ******************************************************************************/ +double doubleTheInput(double x) +{ + return 2 * x; +} +``` + +### Doxygen for C++ Libraries + +The base C++ libraries include Doxygen configurations which generate static +websites from code comments. These documentation sites are published as developer +reference documentation using GitHub Pages. When building the Doxygen site locally, +The site is generated in `docs/html/` and the main page can be accessed at `docs/html/index.html`. +When new releases are made, GitHub Actions workflows are triggered which build and deploy +the Doxygen site to GitHub Pages. + +### MATLAB Wrappers + +Most code in the MATLAB wrapper is actually written in C. In these files, the same +documentation style as noted above for C++ should be used. + +### Python Wrappers + +The Python wrapper code is documented in the [Sphinx](https://sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html) +format. It is recommended to include docstrings for all primary functions, classes, +or structures provided by the Python wrapper. Further, function signatures should +include [type annotation](https://docs.python.org/3/library/typing.html) for inputs +and returned values. Inline or other comments should be included to explain other +variables or functionalities of the code. Below is an example showing the recommended +documentation format. + +```python + +CONSTANT_EXPOSED_BY_MODULE = 42 # A brief comment could explain what this is + +def double_the_input(x: float) -> float: + """This is a brief description of the function. + + This is an optional, longer description of the function. + It can span multiple lines. + + :param x: The input value, and its expected units. + :return: The result y = 2*x + """ + return 2 * x +``` + +### C#/.NET Wrappers + +In C#/.NET, documentation comments are written in +[XML format](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/documentation-comments) +and are used to generate documentation through tools like Visual Studio. Use `` tags to +provide brief descriptions of classes, constants, functions, etc. Functions should +include `` and `` elements for all inputs and outputs. An example +of this documentation style is shown below. + +```csharp +/// +/// Represents a class that contains constants and methods related to calculations. +/// +public class CalculationUtils +{ + /// + /// A constant value exposed by the module. + /// + public const int CONSTANT_EXPOSED_BY_MODULE = 42; + + /// + /// Doubles the input value. + /// + /// The input value to be doubled. + /// The doubled value of the input. + public double DoubleTheInput(double x) + { + // Brief comment explaining what this function does. + return 2 * x; + } +} +``` + +## Testing Code + +When modifying or extending this software, ensure that unit tests are added to +cover your new code. In general, each C++ file in `src/` has a corresponding C++ +file in `tests/` which implements unit tests. If you've added a new file in `tests/`, +make sure to add that file to the executable in `tests/CMakeLists.txt`. + +After compiling the library, you can run unit tests as follows. First, change your +working directory to the `build` directory, then run: + +```bash +ctest +``` diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..add8ca7 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,34 @@ +# SOFTWARE DISCLAIMER / RELEASE + +This software was developed by employees of the National Telecommunications and Information +Administration (NTIA), an agency of the Federal Government and is provided to you +as a public service. Pursuant to Title 15 United States Code Section 105, works +of NTIA employees are not subject to copyright protection within the United States. + +The software is provided by NTIA “AS IS.” NTIA MAKES NO WARRANTY OF ANY KIND, EXPRESS, +IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT AND DATA ACCURACY. NTIA does +not warrant or make any representations regarding the use of the software or the +results thereof, including but not limited to the correctness, accuracy, reliability +or usefulness of the software. + +To the extent that NTIA holds rights in countries other than the United States, +you are hereby granted the non-exclusive irrevocable and unconditional right to +print, publish, prepare derivative works and distribute the NTIA software, in any +medium, or authorize others to do so on your behalf, on a royalty-free basis throughout +the World. + +You may improve, modify, and create derivative works of the software or any portion +of the software, and you may copy and distribute such modifications or works. Modified +works should carry a notice stating that you changed the software and should note +the date and nature of any such change. + +You are solely responsible for determining the appropriateness of using and distributing +the software and you assume all risks associated with its use, including but not +limited to the risks and costs of program errors, compliance with applicable laws, +damage to or loss of data, programs or equipment, and the unavailability or interruption +of operation. This software is not intended to be used in any situation where a failure +could cause risk of injury or damage to property. + +Please provide appropriate acknowledgments of NTIA’s creation of the software in +any copies or derivative works of this software. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..06e73be --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,65 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "TODO-TEMPLATE" +dynamic = ["version"] +description = "TODO-TEMPLATE" +readme = "README.md" +requires-python = ">=3.9" +license = { file = "LICENSE.md" } + +authors = [ + { name = "The Institute for Telecommunication Sciences", email = "code@ntia.gov" }, +] + +keywords = ["TODO-TEMPLATE", "NTIA", "ITS"] + +classifiers = [ + "Intended Audience :: Science/Research", + "Intended Audience :: Telecommunications Industry", + "License :: Public Domain", + "Natural Language :: English", + "Operating System :: MacOS", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] + +[project.optional-dependencies] +tests = [ + "pytest>=8.2.0,<9.0", + "pytest-cov>=6.0.0,<7.0", + "tox>=4.23.2,<5.0", # Keep in sync with tox.ini minimum_version +] +dev = [ + "hatchling>=1.5.0,<2.0", + "pre-commit>=4.0.1,<5.0", + "proplib_template[tests]", # TODO-TEMPLATE set to this package +] + +[project.urls] +"Python Wrapper Source" = "https://github.com/NTIA/TODO-TEMPLATE" +"Python Wrapper Bug Tracker" = "https://github.com/NTIA/TODO-TEMPLATE/issues" +"C++ Source" = "https://github.com/NTIA/TODO-TEMPLATE" +"NTIA GitHub" = "https://github.com/NTIA" +"ITS Website" = "https://its.ntia.gov" + +[tool.hatch.version] +# TODO-TEMPLATE: Set to this package's `__init__.py` +path = "src/ITS/.../__init__.py" + +[tool.hatch.build.targets.wheel] +packages = ["src/ITS"] +ignore-vcs = true + +[tool.cibuildwheel] +test-command = "pytest ." +test-requires = "pytest" diff --git a/src/ITS/PropLibTemplate/__init__.py b/src/ITS/PropLibTemplate/__init__.py new file mode 100644 index 0000000..9145e88 --- /dev/null +++ b/src/ITS/PropLibTemplate/__init__.py @@ -0,0 +1,11 @@ +# Version X.Y.Z: X.Y is the version of the C++ source, +# and Z is the version of this Python wrapper +__version__ = "1.0.0" + +# TODO-TEMPLATE import the functions and objects for the package to expose +# from .proplib_template import ( + +# ) + +# TODO-TEMPLATE: Put the name of the module here +__all__ = ["proplib_template"] diff --git a/src/ITS/PropLibTemplate/proplib_loader.py b/src/ITS/PropLibTemplate/proplib_loader.py new file mode 100644 index 0000000..85ce5dc --- /dev/null +++ b/src/ITS/PropLibTemplate/proplib_loader.py @@ -0,0 +1,101 @@ +""" +This module defines a class for interacting with a compiled shared library using +the ctypes library in Python. It manages loading the library, defining some +expected function prototypes, and parsing exit codes returned by the library functions. + +The class `PropLibCDLL` is a thin wrapper for `ctypes.CDLL` which automatically +determines the appropriate shared library file based on the operating system and +provides methods for checking function return codes. + +Classes: +-------- +- PropLibCDLL: A subclass of `ctypes.CDLL` that manages loading a PropLib shared + library and provides error checking for its functions. + +Methods: +-------- +- __init__(name): + Initializes the `PropLibCDLL` instance by loading the specified library and + setting up the expected function prototypes. + +- get_lib_name(lib_name: str) -> str: + Static method that constructs the full filename of the library based on the + current platform. + +- err_check(rtn_code: int) -> None: + Checks the return code from the library's function call and raises a RuntimeError + with the associated error message if the return code indicates an error. + +Usage: +------ +1. Create an instance of `PropLibCDLL` with the name of the shared library (without + extension). +2. Call functions from the library using the instance. +3. Use `err_check` to handle error codes returned by those functions. + +Example: +-------- +```python +lib = PropLibCDLL("SomePropLibLibrary-1.0") +return_code = lib.SomeLibraryFunction() +lib.err_check(return_code) +``` +""" +import platform +from ctypes import * +from pathlib import Path + +class PropLibCDLL(CDLL): + def __init__(self, name): + full_name = self.get_lib_name(name) + super().__init__(full_name) + # Define expected function prototypes + self.GetReturnStatusCharArray.restype = POINTER(c_char_p) + self.GetReturnStatusCharArray.argtypes = (c_int,) + self.FreeReturnStatusCharArray.restype = None + self.FreeReturnStatusCharArray.argtypes = (POINTER(c_char_p),) + + @staticmethod + def get_lib_name(lib_name: str) -> str: + """Get the full filename of the library specified by `lib_name`. + + This function appends the correct file extension based on the current platform, + and prepends the full absolute file path. The shared library is expected + to exist in the same directory as this file. + + :param lib_name: The library name, with no extension or path, e.g., "P2108-1.0" + :raises NotImplementedError: For platforms other than Windows, Linux, or macOS. + :return: The full filename, including path and extension, of the library. + """ + # Load the compiled library + if platform.uname()[0] == "Windows": + lib_name += ".dll" + elif platform.uname()[0] == "Linux": + lib_name += ".so" + elif platform.uname()[0] == "Darwin": + lib_name += ".dylib" + else: + raise NotImplementedError("Your OS is not yet supported") + # Library should be in the same directory as this file + lib_path = Path(__file__).parent / lib_name + return str(lib_path.resolve()) + + + def err_check(self, rtn_code: int) -> None: + """Parse the library's return code and raise an error if one occurred. + + Returns immediately for `rtn_code == 0`, otherwise retrieves the + status message string from the underlying library and raises a + RuntimeError with the status message. + + :param rtn_code: Integer return code from the underlying library. + :raises RuntimeError: For any non-zero inputs. + :return: None + """ + if rtn_code == 0: + return + else: + msg = self.GetReturnStatusCharArray(c_int(rtn_code)) + msg_str = cast(msg, c_char_p).value.decode("utf-8") + self.FreeReturnStatusCharArray(msg) + raise RuntimeError(msg_str) diff --git a/src/ITS/PropLibTemplate/proplib_template.py b/src/ITS/PropLibTemplate/proplib_template.py new file mode 100644 index 0000000..7e8c4d5 --- /dev/null +++ b/src/ITS/PropLibTemplate/proplib_template.py @@ -0,0 +1,19 @@ +# TODO-TEMPLATE: Rename this file and fix the import namespace +from ITS.PropLibTemplate.proplib_loader import PropLibCDLL +from ctypes import * + +# TODO-TEMPLATE: Load the shared library. Example: +# lib = PropLibCDLL("P2108-1.0") + +# Define function prototypes +# TODO-TEMPLATE add function prototypes here. Each function should have +# its restype and argtypes defined. Examples: +# lib.AeronauticalStatisticalModel.restype = c_int +# lib.AeronauticalStatisticalModel.argtypes = ( +# c_double, +# c_double, +# c_double, +# POINTER(c_double), +# ) + +# TODO-TEMPLATE: Populate this file with wrapper functions which call the library diff --git a/tests/test_proplib_template.py b/tests/test_proplib_template.py new file mode 100644 index 0000000..814317e --- /dev/null +++ b/tests/test_proplib_template.py @@ -0,0 +1,21 @@ +# TODO-TEMPLATE: Rename this file +import csv +from pathlib import Path + +import pytest + +# TODO-TEMPLATE: Import the python wrapper +from ITS import PropLibTemplate + +# Test data is expected to exist in parent repository +# (i.e., that this Python wrapper repo is cloned as a submodule of the base repo) +TEST_DATA_DIR = (Path(__file__).parent.parent.parent.parent / "tests") / "data" +ABSTOL__DB = 0.1 # Absolute tolerance, in dB, to ensure outputs match expected value + +def read_csv_test_data(filename: str): + with open(TEST_DATA_DIR / filename) as f: + reader = csv.reader(f) + next(reader) # Skip header row + for row in reader: + # yield (inputs, rtn, output) + yield tuple(map(float, row[:-2])), int(row[-2]), float(row[-1]) \ No newline at end of file diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..2104a05 --- /dev/null +++ b/tox.ini @@ -0,0 +1,25 @@ +[tox] +env_list = + py39 + py310 + py311 + py312 + py313 +min_version = 4.23.2 +skip_missing_interpreters = true +no_package = false + +[testenv] +description = Run tests with pytest and generate coverage report +package = wheel +wheel_build_env = .pkg +extras = tests +commands = pytest --cov-report term-missing --no-cov-on-fail --cov {posargs} + +[gh] ; GitHub Actions CI with tox-gh +python = + 3.9 = py39 + 3.10 = py310 + 3.11 = py311 + 3.12 = py312 + 3.13 = py313 From 6b9b0fbf38fd8b81d5306b71ae38b48f51fb3f65 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Fri, 1 Nov 2024 19:08:47 -0400 Subject: [PATCH 03/57] Run pre-commit hooks on all files --- CONTRIBUTING.md | 2 +- src/ITS/PropLibTemplate/proplib_loader.py | 5 +++-- src/ITS/PropLibTemplate/proplib_template.py | 7 ++++--- tests/test_proplib_template.py | 3 ++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5f75e90..f4c5d11 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -203,7 +203,7 @@ Below are some examples of how CMake can be called to compile this software. ```bash # Configure and compile in release configuration -cmake --preset release +cmake --preset release cmake --build --preset release # Use the release configuration but don't build Doxygen docs diff --git a/src/ITS/PropLibTemplate/proplib_loader.py b/src/ITS/PropLibTemplate/proplib_loader.py index 85ce5dc..ff8312d 100644 --- a/src/ITS/PropLibTemplate/proplib_loader.py +++ b/src/ITS/PropLibTemplate/proplib_loader.py @@ -41,10 +41,12 @@ lib.err_check(return_code) ``` """ + import platform from ctypes import * from pathlib import Path + class PropLibCDLL(CDLL): def __init__(self, name): full_name = self.get_lib_name(name) @@ -62,7 +64,7 @@ def get_lib_name(lib_name: str) -> str: This function appends the correct file extension based on the current platform, and prepends the full absolute file path. The shared library is expected to exist in the same directory as this file. - + :param lib_name: The library name, with no extension or path, e.g., "P2108-1.0" :raises NotImplementedError: For platforms other than Windows, Linux, or macOS. :return: The full filename, including path and extension, of the library. @@ -80,7 +82,6 @@ def get_lib_name(lib_name: str) -> str: lib_path = Path(__file__).parent / lib_name return str(lib_path.resolve()) - def err_check(self, rtn_code: int) -> None: """Parse the library's return code and raise an error if one occurred. diff --git a/src/ITS/PropLibTemplate/proplib_template.py b/src/ITS/PropLibTemplate/proplib_template.py index 7e8c4d5..737dcb7 100644 --- a/src/ITS/PropLibTemplate/proplib_template.py +++ b/src/ITS/PropLibTemplate/proplib_template.py @@ -1,7 +1,8 @@ -# TODO-TEMPLATE: Rename this file and fix the import namespace -from ITS.PropLibTemplate.proplib_loader import PropLibCDLL +# TODO-TEMPLATE: Rename this file to your library name from ctypes import * +from .proplib_loader import PropLibCDLL + # TODO-TEMPLATE: Load the shared library. Example: # lib = PropLibCDLL("P2108-1.0") @@ -15,5 +16,5 @@ # c_double, # POINTER(c_double), # ) - + # TODO-TEMPLATE: Populate this file with wrapper functions which call the library diff --git a/tests/test_proplib_template.py b/tests/test_proplib_template.py index 814317e..22d919d 100644 --- a/tests/test_proplib_template.py +++ b/tests/test_proplib_template.py @@ -12,10 +12,11 @@ TEST_DATA_DIR = (Path(__file__).parent.parent.parent.parent / "tests") / "data" ABSTOL__DB = 0.1 # Absolute tolerance, in dB, to ensure outputs match expected value + def read_csv_test_data(filename: str): with open(TEST_DATA_DIR / filename) as f: reader = csv.reader(f) next(reader) # Skip header row for row in reader: # yield (inputs, rtn, output) - yield tuple(map(float, row[:-2])), int(row[-2]), float(row[-1]) \ No newline at end of file + yield tuple(map(float, row[:-2])), int(row[-2]), float(row[-1]) From 7d0980697df869bb527e7abf1178a3bb0ccd33c2 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Fri, 1 Nov 2024 19:08:59 -0400 Subject: [PATCH 04/57] Fix version number typo --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 06e73be..d227fa1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,7 +40,7 @@ tests = [ "tox>=4.23.2,<5.0", # Keep in sync with tox.ini minimum_version ] dev = [ - "hatchling>=1.5.0,<2.0", + "hatchling>=1.25.0,<2.0", "pre-commit>=4.0.1,<5.0", "proplib_template[tests]", # TODO-TEMPLATE set to this package ] From 97cdc0d632b4162384b058b8f9a93b23aab893a6 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Fri, 1 Nov 2024 19:09:14 -0400 Subject: [PATCH 05/57] Add CMakeLists.txt --- CMakeLists.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..594d238 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,16 @@ +########################################### +## COPY COMPILED LIBRARY INTO WRAPPER +########################################### +# This file is expected to be called from a higher-level +# CMakeLists.txt when compiling the C++ library. + +# Where to place compiled library for Python wrapper +# TODO-TEMPLATE: Update this directory for your library namespace +set(PYTHON_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/ITS/.../${LIB_NAME}/) + +add_custom_target( + COPY_LIB_TO_PYTHON ALL + COMMAND ${CMAKE_COMMAND} -E copy $ ${PYTHON_LIB_DIR} + DEPENDS ${LIB_NAME} + COMMENT "Copying library to Python wrapper directory" +) From 383fbb7f64b23ba0fb73a636330a227ec43b52e7 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:06:03 -0500 Subject: [PATCH 06/57] Remove default_language_version --- .pre-commit-config.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 98651e8..7b9f374 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,3 @@ -default_language_version: - python: python3.9 repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 From 5854d6f16c4d06b8293fd73b85292f3af3980c28 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:25:21 -0500 Subject: [PATCH 07/57] Update template readme --- README.md | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..8ebf1ec --- /dev/null +++ b/README.md @@ -0,0 +1,154 @@ +# NTIA/ITS Propagation Library Template Python Wrapper # + + +[![NTIA/ITS PropLib][proplib-badge]][proplib-link] + +[proplib-badge]: https://img.shields.io/badge/PropLib-badge?label=%F0%9F%87%BA%F0%9F%87%B8%20NTIA%2FITS&labelColor=162E51&color=D63E04 +[proplib-link]: https://ntia.github.io/propagation-library-wiki +[gh-actions-test-badge]: https://img.shields.io/github/actions/workflow/status/NTIA/TODO-TEMPLATE/tox.yml?branch=main&logo=pytest&logoColor=ffffff&label=Build%2FTests&labelColor=162E51 +[gh-actions-test-link]: https://github.com/NTIA/TODO-TEMPLATE/actions/workflows/tox.yml +[gh-releases-badge]: https://img.shields.io/github/v/release/NTIA/TODO-TEMPLATE?logo=github&label=Release&labelColor=162E51&color=D63E04 +[gh-releases-link]: https://github.com/NTIA/TODO-TEMPLATE/releases +[gh-issues-badge]: https://img.shields.io/github/issues/NTIA/TODO-TEMPLATE?logo=github&label=Issues&labelColor=162E51 +[gh-issues-link]: https://github.com/NTIA/TODO-TEMPLATE/issues +[doi-badge]: https://img.shields.io/badge/{TODO-TEMPLATE-ALL-VERSIONS-DOI}-x?logo=doi&logoColor=ffffff&labelColor=162E51&color=D63E04 +[doi-link]: https://zenodo.org/badge/latestdoi/{TODO-TEMPLATE-REPOSITORY-ID} + + +This code repository is a template repository for Python wrappers in the NTIA/ITS +Propagation Library (PropLib). This template is intended for developers wishing +to develop a cross-platform Python interface to a compiled C++ library as part of +PropLib. Instructions on how to use this repository are found in its +[GitHub Wiki](https://github.com/NTIA/proplib-template-python/wiki). + +Additional template repositories exist for building the C++ base repository and the +C#/.NET and MATLAB wrappers. See: + +- [NTIA/proplib-template](https://github.com/NTIA/proplib-template) +- [NTIA/proplib-template-dotnet](https://github.com/NTIA/proplib-template-dotnet) +- [NTIA/proplib-template-matlab](https://github.com/NTIA/proplib-template-matlab) + +## Contact ## + +For questions about using this template repository, contact + + From 43193baf43627c67ee1a6b2e3edcd46c1afff329 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:25:53 -0500 Subject: [PATCH 08/57] Make template project buildable --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d227fa1..1c842e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "TODO-TEMPLATE" +name = "proplib-template" # TODO-TEMPLATE update package name dynamic = ["version"] description = "TODO-TEMPLATE" readme = "README.md" @@ -42,7 +42,7 @@ tests = [ dev = [ "hatchling>=1.25.0,<2.0", "pre-commit>=4.0.1,<5.0", - "proplib_template[tests]", # TODO-TEMPLATE set to this package + "proplib-template[tests]", # TODO-TEMPLATE set to this package ] [project.urls] @@ -54,7 +54,7 @@ dev = [ [tool.hatch.version] # TODO-TEMPLATE: Set to this package's `__init__.py` -path = "src/ITS/.../__init__.py" +path = "src/ITS/PropLibTemplate/__init__.py" [tool.hatch.build.targets.wheel] packages = ["src/ITS"] From 2e2408390b83340f20f447a9547667c5da41185d Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:26:47 -0500 Subject: [PATCH 09/57] Make template project testable --- tests/test_proplib_template.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test_proplib_template.py b/tests/test_proplib_template.py index 22d919d..91c4072 100644 --- a/tests/test_proplib_template.py +++ b/tests/test_proplib_template.py @@ -4,7 +4,7 @@ import pytest -# TODO-TEMPLATE: Import the python wrapper +# TODO-TEMPLATE: Import the python wrapper package from ITS import PropLibTemplate # Test data is expected to exist in parent repository @@ -13,6 +13,7 @@ ABSTOL__DB = 0.1 # Absolute tolerance, in dB, to ensure outputs match expected value +# TODO-TEMPLATE: Update CSV reader based on test data CSV structure def read_csv_test_data(filename: str): with open(TEST_DATA_DIR / filename) as f: reader = csv.reader(f) @@ -20,3 +21,8 @@ def read_csv_test_data(filename: str): for row in reader: # yield (inputs, rtn, output) yield tuple(map(float, row[:-2])), int(row[-2]), float(row[-1]) + + +# TODO-TEMPLATE: Implement unit tests for this Python wrapper +def test_always_pass(): + return From 673ad90bbd743b1fe7f559e792857d3e88b16240 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:27:40 -0500 Subject: [PATCH 10/57] Add template Zenodo config --- .zenodo.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .zenodo.json diff --git a/.zenodo.json b/.zenodo.json new file mode 100644 index 0000000..4f32142 --- /dev/null +++ b/.zenodo.json @@ -0,0 +1,17 @@ +{ + "creators": [ + { + "orcid": "TODO-TEMPLATE", + "affiliation": "U.S. Department of Commerce, National Telecommunications and Information Administration, Institute for Telecommunication Sciences", + "name": "TODO-TEMPLATE" + } + ], + "license": "NTIA Public Domain", + "title": "TODO-TEMPLATE, Python Wrapper", + "upload_type": "software", + "version": "TODO-TEMPLATE", + "keywords": ["TODO-TEMPLATE"], + "communities": [ + {"identifier": "its-proplib"} + ] +} From 6af32bc7fba077b7c45d918101a431e386fcebf6 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:30:30 -0500 Subject: [PATCH 11/57] Update installation instructions --- README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8ebf1ec..03bc0eb 100644 --- a/README.md +++ b/README.md @@ -62,10 +62,17 @@ For questions about using this template repository, contact Date: Tue, 12 Nov 2024 15:33:43 -0500 Subject: [PATCH 12/57] Fix template install instruction --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 03bc0eb..3d1ebe2 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ This software is distributed on [PyPi](https://pypi.org/project/TODO-TEMPLATE) a using the following command. ```cmd -pip install p2108 +pip install TODO-TEMPLATE ``` General information about using this model is available on From 88f367582366ae13891df529da18811788297be9 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:00:46 -0500 Subject: [PATCH 13/57] add template public release approval form --- GitHubRepoPublicReleaseApproval.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 GitHubRepoPublicReleaseApproval.md diff --git a/GitHubRepoPublicReleaseApproval.md b/GitHubRepoPublicReleaseApproval.md new file mode 100644 index 0000000..ff4fc4a --- /dev/null +++ b/GitHubRepoPublicReleaseApproval.md @@ -0,0 +1,23 @@ +# GitHub Repository Public Release Approval + +**Project Name:** Office of Spectrum Management R&D - Propagation Library + +**Software Name:** TODO-TEMPLATE + +The software identified above, which is contained within the repository this document is stored in, has met the following criteria for public release: + +1. [ ] The project, including the test criteria, meets the requirements defined in the ITS Software Development Publication Policy for making a repository public. The major pre-established criteria for publication are listed below, and the check mark next to each attests that the criterion has been met. + * [ ] Unit tests are available and the software has been tested against the unit tests + * [ ] Any test data necessary for the code and its unit tests to function is included in this GitHub repository, or in a parent repository which includes this one as a Git submodule. + * [ ] This repository contains complete README and CONTRIBUTING files +1. [ ] This repository adheres to the PropLib Template, and is up-to-date with the latest tagged release of the template repository. +1. [ ] All template or placeholder code has been removed +1. [ ] The README.md file has passed editorial review from the ITS Publications Office. +1. [ ] The project complies with the ITS Code Style Guide or an appropriate style guide as agreed to by the sponsor, project lead, or Supervising Division Chief. +1. [ ] Approved disclaimer and licensing language has been included. + +In order to complete this approval, please create a new branch, upload and commit your version of this Markdown document to that branch, then create a pull request for that branch. The following must login to GitHub and approve that pull request before the pull request can be merged and this repo made public: + +* **Project Lead:** TODO-TEMPLATE + +* **Supervising Division Chief or Release Authority:** TODO-TEMPLATE From a13ae565d6a5844d3c5c9dbd6218aaf4f8035ab4 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:06:57 -0500 Subject: [PATCH 14/57] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3d1ebe2..cb960d7 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,8 @@ This code repository is a template repository for Python wrappers in the NTIA/ITS Propagation Library (PropLib). This template is intended for developers wishing to develop a cross-platform Python interface to a compiled C++ library as part of -PropLib. Instructions on how to use this repository are found in its -[GitHub Wiki](https://github.com/NTIA/proplib-template-python/wiki). +PropLib. Instructions on how to use this repository are found in the +[PropLib Template Wiki](https://github.com/NTIA/proplib-template/wiki). Additional template repositories exist for building the C++ base repository and the C#/.NET and MATLAB wrappers. See: From f704e6e84f82b3a0067eae5e9591467684a357ed Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:23:35 -0500 Subject: [PATCH 15/57] Add template public release form --- GitHubRepoPublicReleaseApproval.md | 39 ++++++++++++++++++------------ 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/GitHubRepoPublicReleaseApproval.md b/GitHubRepoPublicReleaseApproval.md index ff4fc4a..ad5714a 100644 --- a/GitHubRepoPublicReleaseApproval.md +++ b/GitHubRepoPublicReleaseApproval.md @@ -1,23 +1,32 @@ # GitHub Repository Public Release Approval -**Project Name:** Office of Spectrum Management R&D - Propagation Library +**Project Name:** NTIA/OSM Research and Development **Software Name:** TODO-TEMPLATE -The software identified above, which is contained within the repository this document is stored in, has met the following criteria for public release: +The project identified above, which is contained within the repository this +document is stored in, has met the following criteria for public release: -1. [ ] The project, including the test criteria, meets the requirements defined in the ITS Software Development Publication Policy for making a repository public. The major pre-established criteria for publication are listed below, and the check mark next to each attests that the criterion has been met. - * [ ] Unit tests are available and the software has been tested against the unit tests - * [ ] Any test data necessary for the code and its unit tests to function is included in this GitHub repository, or in a parent repository which includes this one as a Git submodule. - * [ ] This repository contains complete README and CONTRIBUTING files -1. [ ] This repository adheres to the PropLib Template, and is up-to-date with the latest tagged release of the template repository. -1. [ ] All template or placeholder code has been removed -1. [ ] The README.md file has passed editorial review from the ITS Publications Office. -1. [ ] The project complies with the ITS Code Style Guide or an appropriate style guide as agreed to by the sponsor, project lead, or Supervising Division Chief. -1. [ ] Approved disclaimer and licensing language has been included. +1. [ ] The project, including the test criteria, meets the requirements defined +in the ITS Software Development Publication Policy for making a repository public. +The major pre-established criteria for publication are listed below, and the check +mark next to each attests that the criterion has been met. + * [ ] Unit tests are available and the software has been tested against the unit tests. + * [ ] The software can be compiled and/or used on Windows, macOS, and Linux. + * [ ] The repository structure and contents follow from the ITS PropLib template, and + all template or placeholder code has been removed. + * [ ] The repository includes the appropriate `LICENSE.md` file +2. [ ] Any test data necessary for the code and its unit tests to function is included in this +GitHub repository, or in a parent repository which includes this one as a Git submodule. +3. [ ] The README.md file has passed editorial review from the ITS Publications Office. +4. [ ] The project complies with the ITS Code Style Guide or an appropriate style +guide as agreed to by the sponsor, project lead, or Supervising Division Chief. +5. [ ] Approved disclaimer and licensing language has been included. -In order to complete this approval, please create a new branch, upload and commit your version of this Markdown document to that branch, then create a pull request for that branch. The following must login to GitHub and approve that pull request before the pull request can be merged and this repo made public: +In order to complete this approval, please create a new branch, upload and commit +your version of this Markdown document to that branch, then create a pull request +for that branch. The following must login to GitHub and approve that pull request +before the pull request can be merged and this repo made public: -* **Project Lead:** TODO-TEMPLATE - -* **Supervising Division Chief or Release Authority:** TODO-TEMPLATE +* Project Lead: TODO-TEMPLATE +* Supervising Division Chief or Release Authority: TODO-TEMPLATE From f4657411675cc1f3c44c1afa52170bb42d34a5cc Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:51:20 -0500 Subject: [PATCH 16/57] Remove zenodo file --- .zenodo.json | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 .zenodo.json diff --git a/.zenodo.json b/.zenodo.json deleted file mode 100644 index 4f32142..0000000 --- a/.zenodo.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "creators": [ - { - "orcid": "TODO-TEMPLATE", - "affiliation": "U.S. Department of Commerce, National Telecommunications and Information Administration, Institute for Telecommunication Sciences", - "name": "TODO-TEMPLATE" - } - ], - "license": "NTIA Public Domain", - "title": "TODO-TEMPLATE, Python Wrapper", - "upload_type": "software", - "version": "TODO-TEMPLATE", - "keywords": ["TODO-TEMPLATE"], - "communities": [ - {"identifier": "its-proplib"} - ] -} From 4fd223171eee19192a366edda726d0ad283e76dd Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:52:36 -0500 Subject: [PATCH 17/57] Add template citation file --- CITATION.cff | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 CITATION.cff diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..b30ea19 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,32 @@ +cff-version: 1.2.0 +title: >- + TODO-TEMPLATE, Python Wrapper +message: Please cite this software using these metadata. +type: software +authors: + - given-names: TODO-TEMPLATE + family-names: TODO-TEMPLATE + name-particle: TODO-TEMPLATE (optional) + email: TODO-TEMPLATE@ntia.gov + affiliation: >- + U.S. Department of Commerce, National + Telecommunications and Information Administration, + Institute for Telecommunication Sciences + orcid: 'https://orcid.org/TODO-TEMPLATE' + - name: >- + U.S. Department of Commerce, National + Telecommunications and Information Administration, + Institute for Telecommunication Sciences + address: 325 Broadway + city: Boulder + country: CO + post-code: '80305' + alias: NTIA/ITS + email: code@ntia.gov + website: 'https://its.ntia.gov' +repository-code: 'https://github.com/NTIA/TODO-TEMPLATE' +url: 'https://ntia.github.io/propagation-library-wiki/models/TODO-TEMPLATE/' +keywords: + - propagation + - TODO-TEMPLATE +version: 1.0.0 From cf69743d33b0ae403e4d433180fc8364f29c1e0e Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:53:14 -0500 Subject: [PATCH 18/57] Remove DOI badge, replace github release with PyPI badge, add disclaimer --- README.md | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index cb960d7..393e579 100644 --- a/README.md +++ b/README.md @@ -3,40 +3,31 @@ [![NTIA/ITS PropLib][proplib-badge]][proplib-link] [proplib-badge]: https://img.shields.io/badge/PropLib-badge?label=%F0%9F%87%BA%F0%9F%87%B8%20NTIA%2FITS&labelColor=162E51&color=D63E04 [proplib-link]: https://ntia.github.io/propagation-library-wiki -[gh-actions-test-badge]: https://img.shields.io/github/actions/workflow/status/NTIA/TODO-TEMPLATE/tox.yml?branch=main&logo=pytest&logoColor=ffffff&label=Build%2FTests&labelColor=162E51 +[gh-actions-test-badge]: https://img.shields.io/github/actions/workflow/status/NTIA/TODO-TEMPLATE/tox.yml?branch=main&logo=pytest&logoColor=ffffff&label=Tests&labelColor=162E51 [gh-actions-test-link]: https://github.com/NTIA/TODO-TEMPLATE/actions/workflows/tox.yml -[gh-releases-badge]: https://img.shields.io/github/v/release/NTIA/TODO-TEMPLATE?logo=github&label=Release&labelColor=162E51&color=D63E04 -[gh-releases-link]: https://github.com/NTIA/TODO-TEMPLATE/releases +[pypi-release-badge]: https://img.shields.io/pypi/v/TODO-TEMPLATE?logo=pypi&logoColor=ffffff&label=Release&labelColor=162E51&color=D63E04 +[pypi-release-link]: https://pypi.org/project/TODO-TEMPLATE [gh-issues-badge]: https://img.shields.io/github/issues/NTIA/TODO-TEMPLATE?logo=github&label=Issues&labelColor=162E51 [gh-issues-link]: https://github.com/NTIA/TODO-TEMPLATE/issues -[doi-badge]: https://img.shields.io/badge/{TODO-TEMPLATE-ALL-VERSIONS-DOI}-x?logo=doi&logoColor=ffffff&labelColor=162E51&color=D63E04 -[doi-link]: https://zenodo.org/badge/latestdoi/{TODO-TEMPLATE-REPOSITORY-ID} This code repository is a template repository for Python wrappers in the NTIA/ITS @@ -62,7 +53,11 @@ For questions about using this template repository, contact [!NOTE] +> The text below indicates this package is distributed on PyPi, +> however it is not yet uploaded. A link will be provided here when available. + +This software is distributed on [PyPi](#) and is easily installable using the following command. ```cmd From 47f6ca766556bc6c99a28dab7266eeb25881cc21 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:57:27 -0500 Subject: [PATCH 19/57] Fix capitalization --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 393e579..3ddf94b 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ TODO-TEMPLATE: Update links in this section > The text below indicates this package is distributed on PyPi, > however it is not yet uploaded. A link will be provided here when available. -This software is distributed on [PyPi](#) and is easily installable +This software is distributed on [PyPI](#) and is easily installable using the following command. ```cmd From 46aee01e0f4f96f28a228b5553a017f660b6f656 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:53:05 -0500 Subject: [PATCH 20/57] Create cff-validator.yml --- .github/workflows/cff-validator.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/cff-validator.yml diff --git a/.github/workflows/cff-validator.yml b/.github/workflows/cff-validator.yml new file mode 100644 index 0000000..dc7d4d8 --- /dev/null +++ b/.github/workflows/cff-validator.yml @@ -0,0 +1,21 @@ +name: Validate CITATION.cff + +on: + push: + paths: CITATION.cff + pull_request: + paths: CITATION.cff + workflow_dispatch: + +jobs: + Validate-CITATION-cff: + runs-on: ubuntu-latest + name: Validate CITATION.cff + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Validate CITATION.cff + uses: dieghernan/cff-validator@v3 From e452154c627f4c54ff7ccb0f0c32f355dcfcb47e Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:58:12 -0500 Subject: [PATCH 21/57] Remove name-particle from template citation file --- CITATION.cff | 1 - 1 file changed, 1 deletion(-) diff --git a/CITATION.cff b/CITATION.cff index b30ea19..94b34d8 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -6,7 +6,6 @@ type: software authors: - given-names: TODO-TEMPLATE family-names: TODO-TEMPLATE - name-particle: TODO-TEMPLATE (optional) email: TODO-TEMPLATE@ntia.gov affiliation: >- U.S. Department of Commerce, National From 72f771243df53bd3e2b740d8388139a02e94ddcd Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:11:23 -0500 Subject: [PATCH 22/57] Make template valid --- CITATION.cff | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CITATION.cff b/CITATION.cff index 94b34d8..98a9812 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -11,7 +11,7 @@ authors: U.S. Department of Commerce, National Telecommunications and Information Administration, Institute for Telecommunication Sciences - orcid: 'https://orcid.org/TODO-TEMPLATE' + orcid: 'https://orcid.org/0000-0000-0000-0000' - name: >- U.S. Department of Commerce, National Telecommunications and Information Administration, From af0d8b5c4f5c2f3af1953f3acd9cddca4cff20b5 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:33:59 -0500 Subject: [PATCH 23/57] Fix file filter in CFF validator --- .github/workflows/cff-validator.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cff-validator.yml b/.github/workflows/cff-validator.yml index dc7d4d8..a01dee3 100644 --- a/.github/workflows/cff-validator.yml +++ b/.github/workflows/cff-validator.yml @@ -2,9 +2,13 @@ name: Validate CITATION.cff on: push: - paths: CITATION.cff + paths: + - CITATION.cff + - .github/workflows/cff-validator.yml pull_request: - paths: CITATION.cff + paths: + - CITATION.cff + - .github/workflows/cff-validator.yml workflow_dispatch: jobs: From 6e5b86ec9db721bdc420b81057efe8cc6f5f82a1 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Fri, 22 Nov 2024 13:47:41 -0500 Subject: [PATCH 24/57] Test fixing path filters --- .github/workflows/cff-validator.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cff-validator.yml b/.github/workflows/cff-validator.yml index a01dee3..83d75d0 100644 --- a/.github/workflows/cff-validator.yml +++ b/.github/workflows/cff-validator.yml @@ -3,12 +3,12 @@ name: Validate CITATION.cff on: push: paths: - - CITATION.cff - - .github/workflows/cff-validator.yml + - 'CITATION.cff' + - '.github/workflows/cff-validator.yml' pull_request: paths: - - CITATION.cff - - .github/workflows/cff-validator.yml + - 'CITATION.cff' + - '.github/workflows/cff-validator.yml' workflow_dispatch: jobs: From dabc99cb2d507de4336ce99a1e0f532651c3c606 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Fri, 22 Nov 2024 13:51:29 -0500 Subject: [PATCH 25/57] Add link to template test data repo --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3ddf94b..eabb052 100644 --- a/README.md +++ b/README.md @@ -36,12 +36,13 @@ to develop a cross-platform Python interface to a compiled C++ library as part o PropLib. Instructions on how to use this repository are found in the [PropLib Template Wiki](https://github.com/NTIA/proplib-template/wiki). -Additional template repositories exist for building the C++ base repository and the -C#/.NET and MATLAB wrappers. See: +Additional template repositories exist for building the C++ base repository, the .NET +and MATLAB wrappers, and the test data repository. See: - [NTIA/proplib-template](https://github.com/NTIA/proplib-template) - [NTIA/proplib-template-dotnet](https://github.com/NTIA/proplib-template-dotnet) - [NTIA/proplib-template-matlab](https://github.com/NTIA/proplib-template-matlab) +- [NTIA/proplib-template-test-data](https://github.com/NTIA/proplib-template-test-data) ## Contact ## From d3e919292c83f83b96186efb8d33c5047899d46e Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:56:10 -0500 Subject: [PATCH 26/57] Fix incorrect field --- CITATION.cff | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CITATION.cff b/CITATION.cff index 98a9812..3d07367 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -18,8 +18,9 @@ authors: Institute for Telecommunication Sciences address: 325 Broadway city: Boulder - country: CO + country: US post-code: '80305' + region: Colorado alias: NTIA/ITS email: code@ntia.gov website: 'https://its.ntia.gov' From 670d3b1170fed9ff7db0109ed9280c1836ba3a77 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Mon, 2 Dec 2024 18:25:24 -0500 Subject: [PATCH 27/57] Update approval form for test data requirements --- GitHubRepoPublicReleaseApproval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitHubRepoPublicReleaseApproval.md b/GitHubRepoPublicReleaseApproval.md index ad5714a..85235a5 100644 --- a/GitHubRepoPublicReleaseApproval.md +++ b/GitHubRepoPublicReleaseApproval.md @@ -17,7 +17,7 @@ mark next to each attests that the criterion has been met. all template or placeholder code has been removed. * [ ] The repository includes the appropriate `LICENSE.md` file 2. [ ] Any test data necessary for the code and its unit tests to function is included in this -GitHub repository, or in a parent repository which includes this one as a Git submodule. +GitHub repository, either directly or as a linked Git submodule. 3. [ ] The README.md file has passed editorial review from the ITS Publications Office. 4. [ ] The project complies with the ITS Code Style Guide or an appropriate style guide as agreed to by the sponsor, project lead, or Supervising Division Chief. From ad6bb23eb17a40b9489a61314cb24c1d2a17f90b Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Mon, 2 Dec 2024 18:29:38 -0500 Subject: [PATCH 28/57] Add zenodo template and README badge --- .zenodo.json | 36 ++++++++++++++++++++++++++++++++++++ README.md | 7 +++++++ 2 files changed, 43 insertions(+) create mode 100644 .zenodo.json diff --git a/.zenodo.json b/.zenodo.json new file mode 100644 index 0000000..c78dbcb --- /dev/null +++ b/.zenodo.json @@ -0,0 +1,36 @@ +{ + "upload_type": "software", + "publication_date": "TODO-TEMPLATE", + "title": "TODO-TEMPLATE", + "creators": [ + { + "name": "TODO-TEMPLATE", + "affiliation": "U.S. Department of Commerce, National Telecommunications and Information Administration, Institute for Telecommunication Sciences", + "orcid": "TODO-TEMPLATE" + } + ], + "description": "TODO-TEMPLATE. Make this the same as the abstract.", + "access_right": "open", + "keywords": [ + "TODO-TEMPLATE", + "TODO-TEMPLATE" + ], + "related_identifiers": [ + { + "identifier": "https://github.com/NTIA/TODO-TEMPLATE", + "relation": "isSupplementTo", + "resource_type": "software" + }, + { + "identifier": "https://github.com/NTIA/TODO-TEMPLATE-test-data", + "relation": "isSupplementedBy", + "resource_type": "software" + }, + { + "identifier": "https://ntia.github.io/propagation-library-wiki/models/TODO-TEMPLATE/", + "relation": "isDocumentedBy", + "resource_type": "softwaredocumentation" + } + ], + "version": "TODO-TEMPLATE" +} diff --git a/README.md b/README.md index eabb052..5262e00 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ - The fourth badge displays open GitHub Issues - Update the repository name in [gh-issues-badge] - Update the repository name in [gh-issues-link] +- The fifth badge displays and links the Zenodo DOI + - Get your repository ID from https://api.github.com/repos/NTIA/{repo} + - Or, if private, follow: https://stackoverflow.com/a/47223479 + - Populate the repository ID in [doi-link] and [doi-badge] --> [![NTIA/ITS PropLib][proplib-badge]][proplib-link] [proplib-badge]: https://img.shields.io/badge/PropLib-badge?label=%F0%9F%87%BA%F0%9F%87%B8%20NTIA%2FITS&labelColor=162E51&color=D63E04 [proplib-link]: https://ntia.github.io/propagation-library-wiki @@ -28,6 +33,8 @@ [pypi-release-link]: https://pypi.org/project/TODO-TEMPLATE [gh-issues-badge]: https://img.shields.io/github/issues/NTIA/TODO-TEMPLATE?logo=github&label=Issues&labelColor=162E51 [gh-issues-link]: https://github.com/NTIA/TODO-TEMPLATE/issues +[doi-badge]: https://zenodo.org/badge/TODO-TEMPLATE.svg +[doi-link]: https://zenodo.org/badge/latestdoi/TODO-TEMPLATE This code repository is a template repository for Python wrappers in the NTIA/ITS From 8e89044a641479c0ffa9037fa8f3eb676da8ca77 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Mon, 2 Dec 2024 18:30:09 -0500 Subject: [PATCH 29/57] Fix resource_type in template zenodo file --- .zenodo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.zenodo.json b/.zenodo.json index c78dbcb..6bda553 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -24,7 +24,7 @@ { "identifier": "https://github.com/NTIA/TODO-TEMPLATE-test-data", "relation": "isSupplementedBy", - "resource_type": "software" + "resource_type": "dataset" }, { "identifier": "https://ntia.github.io/propagation-library-wiki/models/TODO-TEMPLATE/", From f470b5dbe8740e00bd1bf49f5e90da686bbfc3bb Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 3 Dec 2024 09:12:40 -0500 Subject: [PATCH 30/57] Update markdownlink pre-commit hook --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7b9f374..c7ec2e1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,7 +33,7 @@ repos: - id: black types: [file, python] - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.42.0 + rev: v0.43.0 hooks: - id: markdownlint types: [file, markdown] From 21235c741c2797e0018770ae7844b5afb4425453 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:16:55 -0500 Subject: [PATCH 31/57] Migrate tox configuration into pyproject.toml --- pyproject.toml | 29 ++++++++++++++++++++++++++--- tox.ini | 25 ------------------------- 2 files changed, 26 insertions(+), 28 deletions(-) delete mode 100644 tox.ini diff --git a/pyproject.toml b/pyproject.toml index 1c842e8..573e5db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "proplib-template" # TODO-TEMPLATE update package name +name = "proplib-template" # TODO-TEMPLATE update package name dynamic = ["version"] description = "TODO-TEMPLATE" readme = "README.md" @@ -37,12 +37,12 @@ classifiers = [ tests = [ "pytest>=8.2.0,<9.0", "pytest-cov>=6.0.0,<7.0", - "tox>=4.23.2,<5.0", # Keep in sync with tox.ini minimum_version + "tox>=4.21.1,<5.0", # Keep in sync with tool.tox.min_version ] dev = [ "hatchling>=1.25.0,<2.0", "pre-commit>=4.0.1,<5.0", - "proplib-template[tests]", # TODO-TEMPLATE set to this package + "proplib-template[tests]", # TODO-TEMPLATE set to this package ] [project.urls] @@ -63,3 +63,26 @@ ignore-vcs = true [tool.cibuildwheel] test-command = "pytest ." test-requires = "pytest" + +[tool.tox] +min_version = "4.21.1" +env_list = ["3.9", "3.10", "3.11", "3.12", "3.13"] +skip_missing_interpreters = true # TODO override this in GHA + +[tool.tox.env.testenv] +description = "Run tests with pytest and generate coverage report" +extras = "tests" +commands = [ + "pytest", + "--cov-report=term-missing", + "--no-cov-on-fail", + "--cov", + { replace = "posargs", extend = true }, +] + +[tool.tox.gh.python] # tox-gh config for GitHub Actions testing +"3.9" = ["3.9"] +"3.10" = ["3.10"] +"3.11" = ["3.11"] +"3.12" = ["3.12"] +"3.13" = ["3.13"] diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 2104a05..0000000 --- a/tox.ini +++ /dev/null @@ -1,25 +0,0 @@ -[tox] -env_list = - py39 - py310 - py311 - py312 - py313 -min_version = 4.23.2 -skip_missing_interpreters = true -no_package = false - -[testenv] -description = Run tests with pytest and generate coverage report -package = wheel -wheel_build_env = .pkg -extras = tests -commands = pytest --cov-report term-missing --no-cov-on-fail --cov {posargs} - -[gh] ; GitHub Actions CI with tox-gh -python = - 3.9 = py39 - 3.10 = py310 - 3.11 = py311 - 3.12 = py312 - 3.13 = py313 From 201c315d06bd31751ac7016c0d58ad729b89f90a Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:17:11 -0500 Subject: [PATCH 32/57] Remove CMakeLists.txt --- CMakeLists.txt | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 594d238..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -########################################### -## COPY COMPILED LIBRARY INTO WRAPPER -########################################### -# This file is expected to be called from a higher-level -# CMakeLists.txt when compiling the C++ library. - -# Where to place compiled library for Python wrapper -# TODO-TEMPLATE: Update this directory for your library namespace -set(PYTHON_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/ITS/.../${LIB_NAME}/) - -add_custom_target( - COPY_LIB_TO_PYTHON ALL - COMMAND ${CMAKE_COMMAND} -E copy $ ${PYTHON_LIB_DIR} - DEPENDS ${LIB_NAME} - COMMENT "Copying library to Python wrapper directory" -) From f1a67b4734e47384a4c7118bcd3c72efb31f10cf Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:59:07 -0500 Subject: [PATCH 33/57] Update test data directory --- tests/test_proplib_template.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test_proplib_template.py b/tests/test_proplib_template.py index 91c4072..00637db 100644 --- a/tests/test_proplib_template.py +++ b/tests/test_proplib_template.py @@ -7,9 +7,8 @@ # TODO-TEMPLATE: Import the python wrapper package from ITS import PropLibTemplate -# Test data is expected to exist in parent repository -# (i.e., that this Python wrapper repo is cloned as a submodule of the base repo) -TEST_DATA_DIR = (Path(__file__).parent.parent.parent.parent / "tests") / "data" +# Test data is expected to exist in extern/-test-data +TEST_DATA_DIR = (Path(__file__).parent.parent / "extern") / "TODO-TEMPLATE" ABSTOL__DB = 0.1 # Absolute tolerance, in dB, to ensure outputs match expected value From 6f6f8accd8124513d3fbd4f64283ff1036964639 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 3 Dec 2024 12:02:15 -0500 Subject: [PATCH 34/57] Update README --- README.md | 55 ++++++++++++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 5262e00..3785637 100644 --- a/README.md +++ b/README.md @@ -91,42 +91,37 @@ this either from the compiling it yourself from the C++ source code. Either way, ensure that the shared library (`.dll`, `.dylib`, or `.so` file) is placed in `src/TODO-TEMPLATE/MODEL-NAMESPACE/`, alongside `__init__.py`. -Below are the steps to build and install the Python package from source, including -compiling the library from the C++ source code. Working installations of Git and -Python (3.9 or above) are required. If compiling the shared library, CMake and a C++ compiler -are also required. +Below are the steps to build and install the Python package from the source code. +Working installations of Git and a [currently-supported version](https://devguide.python.org/versions/) +of Python are required. Additional requirements exist if you want to compile the shared +library from C++ source code; see relevant build instructions +[here](https://github.com/NTIA/TODO-TEMPLATE?tab=readme-ov-file#configure-and-build). + +1. Optionally, configure and activate a virtual environment using a tool such as +[`venv`](https://docs.python.org/3/library/venv.html) or +[conda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). -1. Clone the parent repository, then initialize the Git submodule containing the -Python wrapper. This repository structure makes test data available to the Python -wrapper. +1. Clone this repository, then initialize the Git submodule containing the test data. ```cmd - # Clone the parent repository + # Clone the repository git clone https://github.com/NTIA/TODO-TEMPLATE cd TODO-TEMPLATE - # Initialize Git submodules (wrappers and external dependencies) + # Initialize Git submodule containing test data git submodule init - # Clone the submodules + # Clone the submodule git submodule update ``` -1. Compile the C++ library for your platform, following instructions -[here](https://github.com/NTIA/TODO-TEMPLATE?tab=readme-ov-file#configure-and-build). -Following these instructions should automatically copy the shared library -into the location required by the Python wrapper. - - **OR** - - Download the shared library (`.dll`, `.so`, or `.dylib`) from a - [GitHub Release](https://github.com/NTIA/TODO-TEMPLATE/releases). Then place the - downloaded file in `src/TODO-TEMPLATE/MODEL-NAMESPACE/` (alongside `__init__.py`). +1. Download the shared library (`.dll`, `.so`, or `.dylib`) from a +[GitHub Release](https://github.com/NTIA/TODO-TEMPLATE/releases). Then place the +downloaded file in `src/TODO-TEMPLATE/MODEL-NAMESPACE/` (alongside `__init__.py`). -1. Install the local package and development dependencies: +1. Install the local package and development dependencies into your current environment: ```cmd - cd wrap/python pip install .[dev] ``` @@ -138,11 +133,9 @@ into the location required by the Python wrapper. ### Running Tests ### -Python unit tests can be run to confirm successful installation. Test data is -expected to be located in the parent repository. Therefore, if you haven't cloned -this repository as a submodule (as described above), you will need to first specify -the location of the test data files in `tests/test_.py` (using the `TEST_DATA_DIR` -variable). Then, run the tests with pytest: +Python unit tests can be run to confirm successful installation. You will need to +clone this repository's test data submodule (as described above). Then, run the tests +with pytest using the following command. ```cmd pytest @@ -152,10 +145,10 @@ pytest TODO-TEMPLATE: Update references -* [ITS Propagation Library Wiki](https://ntia.github.io/propagation-library-wiki) -* [TODO-TEMPLATE Wiki Page](https://ntia.github.io/propagation-library-wiki/models/TODO-TEMPLATE) -* [`TODO-TEMPLATE` C++ API Reference](https://ntia.github.io/TODO-TEMPLATE) -* TODO-TEMPLATE: Link supporting documentation such as ITU-R Recommendations, NTIA reports, etc. +- [ITS Propagation Library Wiki](https://ntia.github.io/propagation-library-wiki) +- [TODO-TEMPLATE Wiki Page](https://ntia.github.io/propagation-library-wiki/models/TODO-TEMPLATE) +- [`TODO-TEMPLATE` C++ API Reference](https://ntia.github.io/TODO-TEMPLATE) +- TODO-TEMPLATE: Link supporting documentation such as ITU-R Recommendations, NTIA reports, etc. ## Contact ## From a7b6084b7182dc72eaa308342bc6f6fb12b02ec0 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 3 Dec 2024 12:02:40 -0500 Subject: [PATCH 35/57] Initialize extern directory for submodule --- extern/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 extern/README.md diff --git a/extern/README.md b/extern/README.md new file mode 100644 index 0000000..eed1724 --- /dev/null +++ b/extern/README.md @@ -0,0 +1,3 @@ +# External Dependencies + +This directory is used for external dependencies and/or Git submodules. From d9ac58d58cc04eeb1388ef9979f7729937054e8c Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 3 Dec 2024 12:05:19 -0500 Subject: [PATCH 36/57] Rename test_utils file --- tests/{test_proplib_template.py => test_utils.py} | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) rename tests/{test_proplib_template.py => test_utils.py} (64%) diff --git a/tests/test_proplib_template.py b/tests/test_utils.py similarity index 64% rename from tests/test_proplib_template.py rename to tests/test_utils.py index 00637db..c96aff4 100644 --- a/tests/test_proplib_template.py +++ b/tests/test_utils.py @@ -1,13 +1,7 @@ -# TODO-TEMPLATE: Rename this file import csv from pathlib import Path -import pytest - -# TODO-TEMPLATE: Import the python wrapper package -from ITS import PropLibTemplate - -# Test data is expected to exist in extern/-test-data +# Test data is expected to exist in extern/TODO-TEMPLATE-test-data TEST_DATA_DIR = (Path(__file__).parent.parent / "extern") / "TODO-TEMPLATE" ABSTOL__DB = 0.1 # Absolute tolerance, in dB, to ensure outputs match expected value @@ -18,10 +12,10 @@ def read_csv_test_data(filename: str): reader = csv.reader(f) next(reader) # Skip header row for row in reader: - # yield (inputs, rtn, output) + # yields (*inputs, rtn, output) yield tuple(map(float, row[:-2])), int(row[-2]), float(row[-1]) -# TODO-TEMPLATE: Implement unit tests for this Python wrapper +# TODO-TEMPLATE: Delete this dummy test and write your own in another file. def test_always_pass(): return From 6f7c9f85c8e5649a0e1a402105e6237d3816d399 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Tue, 3 Dec 2024 12:31:09 -0500 Subject: [PATCH 37/57] Move expected test data directory to tests/data --- extern/README.md | 3 --- tests/test_utils.py | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 extern/README.md diff --git a/extern/README.md b/extern/README.md deleted file mode 100644 index eed1724..0000000 --- a/extern/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# External Dependencies - -This directory is used for external dependencies and/or Git submodules. diff --git a/tests/test_utils.py b/tests/test_utils.py index c96aff4..4a6a2ce 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,8 +1,8 @@ import csv from pathlib import Path -# Test data is expected to exist in extern/TODO-TEMPLATE-test-data -TEST_DATA_DIR = (Path(__file__).parent.parent / "extern") / "TODO-TEMPLATE" +# Test data is expected to exist in tests/data +TEST_DATA_DIR = Path(__file__).parent / "data" ABSTOL__DB = 0.1 # Absolute tolerance, in dB, to ensure outputs match expected value From c90126fc930c929edab0cba0d7755ad627ec6e0b Mon Sep 17 00:00:00 2001 From: Chen Heroy Date: Mon, 9 Dec 2024 09:35:40 -0700 Subject: [PATCH 38/57] initialize LFMF Python wrap --- .../proplib_template.py => Propagation/LFMF/LFMF.py} | 0 src/ITS/{PropLibTemplate => Propagation/LFMF}/__init__.py | 0 src/ITS/{PropLibTemplate => Propagation/LFMF}/proplib_loader.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/ITS/{PropLibTemplate/proplib_template.py => Propagation/LFMF/LFMF.py} (100%) rename src/ITS/{PropLibTemplate => Propagation/LFMF}/__init__.py (100%) rename src/ITS/{PropLibTemplate => Propagation/LFMF}/proplib_loader.py (100%) diff --git a/src/ITS/PropLibTemplate/proplib_template.py b/src/ITS/Propagation/LFMF/LFMF.py similarity index 100% rename from src/ITS/PropLibTemplate/proplib_template.py rename to src/ITS/Propagation/LFMF/LFMF.py diff --git a/src/ITS/PropLibTemplate/__init__.py b/src/ITS/Propagation/LFMF/__init__.py similarity index 100% rename from src/ITS/PropLibTemplate/__init__.py rename to src/ITS/Propagation/LFMF/__init__.py diff --git a/src/ITS/PropLibTemplate/proplib_loader.py b/src/ITS/Propagation/LFMF/proplib_loader.py similarity index 100% rename from src/ITS/PropLibTemplate/proplib_loader.py rename to src/ITS/Propagation/LFMF/proplib_loader.py From 568430b01857403d4e2d3c034d34db6ea2bfec9d Mon Sep 17 00:00:00 2001 From: Chen Heroy Date: Mon, 9 Dec 2024 12:30:18 -0700 Subject: [PATCH 39/57] update README --- CITATION.cff | 18 +++--- GitHubRepoPublicReleaseApproval.md | 6 +- README.md | 94 ++++++++++++------------------ pyproject.toml | 24 ++++---- 4 files changed, 65 insertions(+), 77 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 3d07367..93fe30d 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,17 +1,17 @@ cff-version: 1.2.0 title: >- - TODO-TEMPLATE, Python Wrapper + Low Frequency / Medium Frequency (LF/MF) Propagation Model message: Please cite this software using these metadata. type: software authors: - - given-names: TODO-TEMPLATE - family-names: TODO-TEMPLATE - email: TODO-TEMPLATE@ntia.gov + - family-names: Kozma + given-names: William + name-suffix: Jr. affiliation: >- U.S. Department of Commerce, National Telecommunications and Information Administration, Institute for Telecommunication Sciences - orcid: 'https://orcid.org/0000-0000-0000-0000' + orcid: 'https://orcid.org/0000-0002-7417-4009' - name: >- U.S. Department of Commerce, National Telecommunications and Information Administration, @@ -24,9 +24,11 @@ authors: alias: NTIA/ITS email: code@ntia.gov website: 'https://its.ntia.gov' -repository-code: 'https://github.com/NTIA/TODO-TEMPLATE' -url: 'https://ntia.github.io/propagation-library-wiki/models/TODO-TEMPLATE/' +repository-code: 'https://github.com/NTIA/LFMF-python' +url: 'https://ntia.github.io/propagation-library-wiki/models/LFMF' keywords: + - its - propagation - - TODO-TEMPLATE + - lfmf version: 1.0.0 +date-released: '' diff --git a/GitHubRepoPublicReleaseApproval.md b/GitHubRepoPublicReleaseApproval.md index 85235a5..7c1fc41 100644 --- a/GitHubRepoPublicReleaseApproval.md +++ b/GitHubRepoPublicReleaseApproval.md @@ -2,7 +2,7 @@ **Project Name:** NTIA/OSM Research and Development -**Software Name:** TODO-TEMPLATE +**Software Name:** Low Frequency / Medium Frequency (LF/MF) Propagation Model, Python Wrapper The project identified above, which is contained within the repository this document is stored in, has met the following criteria for public release: @@ -28,5 +28,5 @@ your version of this Markdown document to that branch, then create a pull reques for that branch. The following must login to GitHub and approve that pull request before the pull request can be merged and this repo made public: -* Project Lead: TODO-TEMPLATE -* Supervising Division Chief or Release Authority: TODO-TEMPLATE +* Project Lead: Kozma Jr, William +* Supervising Division Chief or Release Authority: Chris Anderson diff --git a/README.md b/README.md index 3785637..8485084 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# NTIA/ITS Propagation Library Template Python Wrapper # - - [![NTIA/ITS PropLib][proplib-badge]][proplib-link] +[![GitHub Issues][gh-issues-badge]][gh-issues-link] [proplib-badge]: https://img.shields.io/badge/PropLib-badge?label=%F0%9F%87%BA%F0%9F%87%B8%20NTIA%2FITS&labelColor=162E51&color=D63E04 [proplib-link]: https://ntia.github.io/propagation-library-wiki -[gh-actions-test-badge]: https://img.shields.io/github/actions/workflow/status/NTIA/TODO-TEMPLATE/tox.yml?branch=main&logo=pytest&logoColor=ffffff&label=Tests&labelColor=162E51 -[gh-actions-test-link]: https://github.com/NTIA/TODO-TEMPLATE/actions/workflows/tox.yml -[pypi-release-badge]: https://img.shields.io/pypi/v/TODO-TEMPLATE?logo=pypi&logoColor=ffffff&label=Release&labelColor=162E51&color=D63E04 -[pypi-release-link]: https://pypi.org/project/TODO-TEMPLATE -[gh-issues-badge]: https://img.shields.io/github/issues/NTIA/TODO-TEMPLATE?logo=github&label=Issues&labelColor=162E51 -[gh-issues-link]: https://github.com/NTIA/TODO-TEMPLATE/issues -[doi-badge]: https://zenodo.org/badge/TODO-TEMPLATE.svg -[doi-link]: https://zenodo.org/badge/latestdoi/TODO-TEMPLATE - - -This code repository is a template repository for Python wrappers in the NTIA/ITS -Propagation Library (PropLib). This template is intended for developers wishing -to develop a cross-platform Python interface to a compiled C++ library as part of -PropLib. Instructions on how to use this repository are found in the -[PropLib Template Wiki](https://github.com/NTIA/proplib-template/wiki). - -Additional template repositories exist for building the C++ base repository, the .NET -and MATLAB wrappers, and the test data repository. See: - -- [NTIA/proplib-template](https://github.com/NTIA/proplib-template) -- [NTIA/proplib-template-dotnet](https://github.com/NTIA/proplib-template-dotnet) -- [NTIA/proplib-template-matlab](https://github.com/NTIA/proplib-template-matlab) -- [NTIA/proplib-template-test-data](https://github.com/NTIA/proplib-template-test-data) - -## Contact ## - -For questions about using this template repository, contact - - +For technical questions, contact . \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 573e5db..36a6c86 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,9 +3,9 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "proplib-template" # TODO-TEMPLATE update package name +name = "proplib-template" # LFMF-python update package name dynamic = ["version"] -description = "TODO-TEMPLATE" +description = "LFMF-python" readme = "README.md" requires-python = ">=3.9" license = { file = "LICENSE.md" } @@ -14,7 +14,12 @@ authors = [ { name = "The Institute for Telecommunication Sciences", email = "code@ntia.gov" }, ] -keywords = ["TODO-TEMPLATE", "NTIA", "ITS"] +keywords = [ + "propagation", + "LFMF", + "NTIA", + "ITS", +] classifiers = [ "Intended Audience :: Science/Research", @@ -42,19 +47,18 @@ tests = [ dev = [ "hatchling>=1.25.0,<2.0", "pre-commit>=4.0.1,<5.0", - "proplib-template[tests]", # TODO-TEMPLATE set to this package + "LFMF[tests]", ] [project.urls] -"Python Wrapper Source" = "https://github.com/NTIA/TODO-TEMPLATE" -"Python Wrapper Bug Tracker" = "https://github.com/NTIA/TODO-TEMPLATE/issues" -"C++ Source" = "https://github.com/NTIA/TODO-TEMPLATE" +"Python Wrapper Source" = "https://github.com/NTIA/LFMF-python" +"Python Wrapper Bug Tracker" = "https://github.com/NTIA/LFMF-python/issues" +"C++ Source" = "https://github.com/NTIA/LFMF" "NTIA GitHub" = "https://github.com/NTIA" "ITS Website" = "https://its.ntia.gov" [tool.hatch.version] -# TODO-TEMPLATE: Set to this package's `__init__.py` -path = "src/ITS/PropLibTemplate/__init__.py" +path = "src/ITS/Propagation/LFMF/__init__.py" [tool.hatch.build.targets.wheel] packages = ["src/ITS"] @@ -67,7 +71,7 @@ test-requires = "pytest" [tool.tox] min_version = "4.21.1" env_list = ["3.9", "3.10", "3.11", "3.12", "3.13"] -skip_missing_interpreters = true # TODO override this in GHA +skip_missing_interpreters = true [tool.tox.env.testenv] description = "Run tests with pytest and generate coverage report" From 850ec19c828633e886827cae728d866b753932d9 Mon Sep 17 00:00:00 2001 From: Chen Heroy Date: Mon, 9 Dec 2024 13:31:03 -0700 Subject: [PATCH 40/57] update README --- README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8485084..5109dff 100644 --- a/README.md +++ b/README.md @@ -79,11 +79,11 @@ library from C++ source code; see relevant build instructions [here](https://github.com/NTIA/LFMF?tab=readme-ov-file#configure-and-build). 1. Optionally, configure and activate a virtual environment using a tool such as -[`venv`](https://docs.python.org/3/library/venv.html) or -[conda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). +[`venv`](https://docs.python.org/3/library/venv.html) or +[`conda`](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). -2. Clone this repository, then initialize the Git submodule containing the test data. +2. Clone the parent repository, then initialize the Git submodule containing the Python wrapper. This repository structure makes test data available to the Python wrapper. ```cmd # Clone the repository @@ -97,19 +97,22 @@ library from C++ source code; see relevant build instructions git submodule update ``` +3. Compile the C++ library for your platform, following instructions [here](https://github.com/NTIA/LFMF?tab=readme-ov-file#configure-and-build). Following these instructions should automatically copy the shared library into the location required by the Python wrapper. + **OR** Download the shared library (`.dll`, `.so`, or `.dylib`) from a -[GitHub Release](https://github.com/NTIA/LFMF-python/releases). Then place the -downloaded file in `src/LFMF-python/MODEL-NAMESPACE/` (alongside `__init__.py`). +[GitHub Release](https://github.com/NTIA/LFMF/releases). Then place the +downloaded file in `src/ITS/Propagation/LFMF/` (alongside `__init__.py`). -1. Install the local package and development dependencies into your current environment: + +4. Install the local package and development dependencies into your current environment: ```cmd pip install .[dev] ``` -1. To build the wheel for your platform: +5. To build the wheel for your platform: ```cmd hatchling build @@ -130,9 +133,8 @@ pytest LFMF-python: Update references - [ITS Propagation Library Wiki](https://ntia.github.io/propagation-library-wiki) -- [LFMF-python Wiki Page](https://ntia.github.io/propagation-library-wiki/models/LFMF-python) -- [`LFMF-python` C++ API Reference](https://ntia.github.io/LFMF-python) -- LFMF-python: Link supporting documentation such as ITU-R Recommendations, NTIA reports, etc. +- [LFMF Wiki Page](https://ntia.github.io/propagation-library-wiki/models/LFMF) +- [`ITS.Propagation.LFMF` C++ API Reference](https://ntia.github.io/LFMF) ## Contact ## From d9f4f1ca58d499d280b163a0231db9b842d70759 Mon Sep 17 00:00:00 2001 From: Chen Heroy Date: Mon, 9 Dec 2024 13:36:55 -0700 Subject: [PATCH 41/57] update CITATION.cff --- CITATION.cff | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CITATION.cff b/CITATION.cff index 93fe30d..1506133 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,12 +1,13 @@ cff-version: 1.2.0 title: >- - Low Frequency / Medium Frequency (LF/MF) Propagation Model + Low Frequency / Medium Frequency (LF/MF) Propagation Model, Python Wrapper message: Please cite this software using these metadata. type: software authors: - family-names: Kozma given-names: William name-suffix: Jr. + email: wkozma@ntia.gov affiliation: >- U.S. Department of Commerce, National Telecommunications and Information Administration, From 28390ebd862ba048a4e9c629084fc87eead0b4bf Mon Sep 17 00:00:00 2001 From: Chen Heroy Date: Mon, 9 Dec 2024 13:43:56 -0700 Subject: [PATCH 42/57] update CITATION.cff --- CITATION.cff | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 1506133..b1a5bb7 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -7,12 +7,12 @@ authors: - family-names: Kozma given-names: William name-suffix: Jr. - email: wkozma@ntia.gov affiliation: >- U.S. Department of Commerce, National Telecommunications and Information Administration, Institute for Telecommunication Sciences orcid: 'https://orcid.org/0000-0002-7417-4009' + email: wkozma@ntia.gov - name: >- U.S. Department of Commerce, National Telecommunications and Information Administration, @@ -25,11 +25,11 @@ authors: alias: NTIA/ITS email: code@ntia.gov website: 'https://its.ntia.gov' -repository-code: 'https://github.com/NTIA/LFMF-python' +repository-code: 'https://github.com/NTIA/LFMF' url: 'https://ntia.github.io/propagation-library-wiki/models/LFMF' +repository: 'https://github.com/NTIA/LFMF' keywords: - its - propagation - lfmf version: 1.0.0 -date-released: '' From afb6fb185f46fb8b430777bbd9e808d2b78fa837 Mon Sep 17 00:00:00 2001 From: Chen Heroy Date: Tue, 10 Dec 2024 14:13:23 -0700 Subject: [PATCH 43/57] update test_lfmf --- pyproject.toml | 4 +- src/ITS/Propagation/LFMF/LFMF.py | 88 +++++++++++++++++++++++----- src/ITS/Propagation/LFMF/__init__.py | 8 +-- tests/test_lfmf.py | 36 ++++++++++++ tests/test_utils.py | 21 ------- 5 files changed, 114 insertions(+), 43 deletions(-) create mode 100644 tests/test_lfmf.py delete mode 100644 tests/test_utils.py diff --git a/pyproject.toml b/pyproject.toml index 36a6c86..ee93b93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,9 +3,9 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "proplib-template" # LFMF-python update package name +name = "LFMF" # LFMF-python update package name dynamic = ["version"] -description = "LFMF-python" +description = "Python wrapper for Low Frequency / Medium Frequency (LF/MF) Propagation Model" readme = "README.md" requires-python = ">=3.9" license = { file = "LICENSE.md" } diff --git a/src/ITS/Propagation/LFMF/LFMF.py b/src/ITS/Propagation/LFMF/LFMF.py index 737dcb7..3f0cb77 100644 --- a/src/ITS/Propagation/LFMF/LFMF.py +++ b/src/ITS/Propagation/LFMF/LFMF.py @@ -1,20 +1,80 @@ -# TODO-TEMPLATE: Rename this file to your library name from ctypes import * +from enum import IntEnum from .proplib_loader import PropLibCDLL -# TODO-TEMPLATE: Load the shared library. Example: -# lib = PropLibCDLL("P2108-1.0") + +class Polarization(IntEnum): + POLARIZATION__HORIZONTAL = 0 + POLARIZATION__VERTICAL = 1 + + +class SolutionMethod(IntEnum): + METHOD__FLAT_EARTH_CURVE = 0 + METHOD__RESIDUE_SERIES = 1 + + +class Result(Structure): + # C Struct for library outputs + _fields_ = [('A_btl__db', c_double), + ('E_dBuVm', c_double), + ('P_rx__dbm', c_double), + ('method', c_int)] + + +# Load the shared library +lib = PropLibCDLL("LFMF-1.0") # Define function prototypes -# TODO-TEMPLATE add function prototypes here. Each function should have -# its restype and argtypes defined. Examples: -# lib.AeronauticalStatisticalModel.restype = c_int -# lib.AeronauticalStatisticalModel.argtypes = ( -# c_double, -# c_double, -# c_double, -# POINTER(c_double), -# ) - -# TODO-TEMPLATE: Populate this file with wrapper functions which call the library +lib.LFMF.restype = c_int +lib.LFMF.argtypes = ( + c_double, + c_double, + c_double, + c_double, + c_double, + c_double, + c_double, + c_double, + c_int, + POINTER(Result), +) + + +def LFMF(h_tx__meter: float, h_rx__meter: float, f__mhz: float, P_tx__watt: float, + N_s: float, d__km: float, epsilon: float, sigma: float, pol: int) -> Result: + """ + Compute the Low Frequency / Medium Frequency (LF/MF) propagation prediction + + :param h_tx__meter: Height of the transmitter, in meter + :param h_rx__meter: Height of the receiver, in meter + :param f__mhz: Frequency, in MHz + :param P_tx__watt: Transmitter power, in Watts + :param N_s: Surface refractivity, in N-Units + :param d__km: Path distance, in km + :param epsilon: Relative permittivity + :param sigma: Conductivity + :param pol: Polarization + + :raises ValueError: If any input parameter is not in its valid range. + :raises Exception: If an unknown error is encountered. + + :return: In Result class. + """ + result = Result() + lib.err_check( + lib.LFMF( + c_double(h_tx__meter), + c_double(h_rx__meter), + c_double(f__mhz), + c_double(P_tx__watt), + c_double(N_s), + c_double(d__km), + c_double(epsilon), + c_double(sigma), + c_int(int(pol)), + byref(result) + ) + ) + + return result diff --git a/src/ITS/Propagation/LFMF/__init__.py b/src/ITS/Propagation/LFMF/__init__.py index 9145e88..3ec44d4 100644 --- a/src/ITS/Propagation/LFMF/__init__.py +++ b/src/ITS/Propagation/LFMF/__init__.py @@ -2,10 +2,6 @@ # and Z is the version of this Python wrapper __version__ = "1.0.0" -# TODO-TEMPLATE import the functions and objects for the package to expose -# from .proplib_template import ( +from .LFMF import * -# ) - -# TODO-TEMPLATE: Put the name of the module here -__all__ = ["proplib_template"] +__all__ = ["LFMF"] diff --git a/tests/test_lfmf.py b/tests/test_lfmf.py new file mode 100644 index 0000000..14ce9fd --- /dev/null +++ b/tests/test_lfmf.py @@ -0,0 +1,36 @@ +import csv +from pathlib import Path + +import pytest + +from ITS.Propagation import LFMF + + +# Test data is expected to exist in parent repository tests/data +TEST_DATA_DIR = (Path(__file__).parent.parent.parent.parent / "tests") / "data" +ABSTOL__DB = 1.0E-1 # Absolute tolerance, in dB, to ensure outputs match expected value + + +def read_csv_test_data(filename: str): + with open(TEST_DATA_DIR / filename) as f: + reader = csv.reader(f) + next(reader) # Skip header row + for row in reader: + # yields (*inputs, rtn, *outputs) + yield tuple(map(float, row[:-5])), int(row[-5]), tuple(map(float, row[-4:])) + + +@pytest.mark.parametrize( + "inputs,rtn,expected", + read_csv_test_data("LFMF_Examples.csv"), +) +def test_lfmf(inputs, rtn, expected): + if rtn == 0: + result = LFMF.LFMF(*inputs) + assert result.A_btl__db == pytest.approx(expected[0], abs=ABSTOL__DB) + assert result.E_dBuVm == pytest.approx(expected[1], abs=ABSTOL__DB) + assert result.P_rx__dbm == pytest.approx(expected[2], abs=ABSTOL__DB) + assert result.method == int(expected[3]) + else: + with pytest.raises(RuntimeError): + LFMF.LFMF(*inputs) diff --git a/tests/test_utils.py b/tests/test_utils.py deleted file mode 100644 index 4a6a2ce..0000000 --- a/tests/test_utils.py +++ /dev/null @@ -1,21 +0,0 @@ -import csv -from pathlib import Path - -# Test data is expected to exist in tests/data -TEST_DATA_DIR = Path(__file__).parent / "data" -ABSTOL__DB = 0.1 # Absolute tolerance, in dB, to ensure outputs match expected value - - -# TODO-TEMPLATE: Update CSV reader based on test data CSV structure -def read_csv_test_data(filename: str): - with open(TEST_DATA_DIR / filename) as f: - reader = csv.reader(f) - next(reader) # Skip header row - for row in reader: - # yields (*inputs, rtn, output) - yield tuple(map(float, row[:-2])), int(row[-2]), float(row[-1]) - - -# TODO-TEMPLATE: Delete this dummy test and write your own in another file. -def test_always_pass(): - return From eef486c9879e1dc6ef436f5d5e0ce1e2cc9a0180 Mon Sep 17 00:00:00 2001 From: Chen Heroy Date: Tue, 10 Dec 2024 14:59:39 -0700 Subject: [PATCH 44/57] remove not used code --- src/ITS/Propagation/LFMF/LFMF.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/ITS/Propagation/LFMF/LFMF.py b/src/ITS/Propagation/LFMF/LFMF.py index 3f0cb77..5495b63 100644 --- a/src/ITS/Propagation/LFMF/LFMF.py +++ b/src/ITS/Propagation/LFMF/LFMF.py @@ -4,16 +4,6 @@ from .proplib_loader import PropLibCDLL -class Polarization(IntEnum): - POLARIZATION__HORIZONTAL = 0 - POLARIZATION__VERTICAL = 1 - - -class SolutionMethod(IntEnum): - METHOD__FLAT_EARTH_CURVE = 0 - METHOD__RESIDUE_SERIES = 1 - - class Result(Structure): # C Struct for library outputs _fields_ = [('A_btl__db', c_double), From 2a1e86f90a3d5780765fef569fa283be2cd37bd9 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:30:49 -0500 Subject: [PATCH 45/57] Populate zenodo metadata --- .zenodo.json | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index 6bda553..67993b1 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,36 +1,43 @@ { "upload_type": "software", "publication_date": "TODO-TEMPLATE", - "title": "TODO-TEMPLATE", + "title": "Low Frequency / Medium Frequency (LF/MF) Propagation Model, Python Wrapper", "creators": [ { - "name": "TODO-TEMPLATE", + "name": "Heroy, Chen", "affiliation": "U.S. Department of Commerce, National Telecommunications and Information Administration, Institute for Telecommunication Sciences", - "orcid": "TODO-TEMPLATE" + "orcid": "0009-0006-8728-4502" + }, + { + "name": "Romaniello, Anthony W.", + "affiliation": "U.S. Department of Commerce, National Telecommunications and Information Administration, Institute for Telecommunication Sciences", + "orcid": "0000-0001-8437-6504" } ], - "description": "TODO-TEMPLATE. Make this the same as the abstract.", + "description": "This code repository contains a Python wrapper for the NTIA/ITS implementation of the Low Frequency / Medium Frequency (LF/MF) Propagation Model.", "access_right": "open", "keywords": [ - "TODO-TEMPLATE", - "TODO-TEMPLATE" + "propagation", + "communications", + "antennas", + "radio wave propagation" ], "related_identifiers": [ { - "identifier": "https://github.com/NTIA/TODO-TEMPLATE", + "identifier": "https://github.com/NTIA/LFMF", "relation": "isSupplementTo", "resource_type": "software" }, { - "identifier": "https://github.com/NTIA/TODO-TEMPLATE-test-data", + "identifier": "https://github.com/NTIA/LFMF-test-data", "relation": "isSupplementedBy", "resource_type": "dataset" }, { - "identifier": "https://ntia.github.io/propagation-library-wiki/models/TODO-TEMPLATE/", + "identifier": "https://ntia.github.io/propagation-library-wiki/models/LFMF/", "relation": "isDocumentedBy", "resource_type": "softwaredocumentation" } ], - "version": "TODO-TEMPLATE" + "version": "1.1.0" } From df9aadd3318d3a3d8dff07e0ae6444dab89f6c0a Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:31:01 -0500 Subject: [PATCH 46/57] Update name formatting --- GitHubRepoPublicReleaseApproval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitHubRepoPublicReleaseApproval.md b/GitHubRepoPublicReleaseApproval.md index 7c1fc41..102de20 100644 --- a/GitHubRepoPublicReleaseApproval.md +++ b/GitHubRepoPublicReleaseApproval.md @@ -28,5 +28,5 @@ your version of this Markdown document to that branch, then create a pull reques for that branch. The following must login to GitHub and approve that pull request before the pull request can be merged and this repo made public: -* Project Lead: Kozma Jr, William +* Project Lead: William Kozma, Jr. * Supervising Division Chief or Release Authority: Chris Anderson From d109efff2de48db3fbd8ce2b4ac1dc8b9e4ed8d9 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:39:13 -0500 Subject: [PATCH 47/57] Update README contenst --- README.md | 77 +++++++++++++++++++------------------------------------ 1 file changed, 26 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 5109dff..dfb7b1f 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,34 @@ -# Low Frequency / Medium Frequency (LF/MF) Propagation Model, Python Wrapper # - - +# Low Frequency / Medium Frequency (LF/MF) Propagation Model, Python® Wrapper # + [![NTIA/ITS PropLib][proplib-badge]][proplib-link] [![GitHub Issues][gh-issues-badge]][gh-issues-link] - + [proplib-badge]: https://img.shields.io/badge/PropLib-badge?label=%F0%9F%87%BA%F0%9F%87%B8%20NTIA%2FITS&labelColor=162E51&color=D63E04 [proplib-link]: https://ntia.github.io/propagation-library-wiki [gh-actions-test-badge]: https://img.shields.io/github/actions/workflow/status/NTIA/LFMF-python/tox.yml?branch=main&logo=pytest&logoColor=ffffff&label=Tests&labelColor=162E51 [gh-actions-test-link]: https://github.com/NTIA/LFMF-python/actions/workflows/tox.yml -[pypi-release-badge]: https://img.shields.io/pypi/v/LFMF-python?logo=pypi&logoColor=ffffff&label=Release&labelColor=162E51&color=D63E04 -[pypi-release-link]: https://pypi.org/project/LFMF-python +[pypi-release-badge]: https://img.shields.io/pypi/v/proplib-lfmf?logo=pypi&logoColor=ffffff&label=Release&labelColor=162E51&color=D63E04 +[pypi-release-link]: https://pypi.org/project/proplib-lfmf [gh-issues-badge]: https://img.shields.io/github/issues/NTIA/LFMF-python?logo=github&label=Issues&labelColor=162E51 [gh-issues-link]: https://github.com/NTIA/LFMF-python/issues -[doi-badge]: https://zenodo.org/badge/LFMF-python.svg -[doi-link]: https://zenodo.org/badge/latestdoi/LFMF-python +[doi-badge]: https://zenodo.org/badge/896234119.svg +[doi-link]: https://zenodo.org/badge/latestdoi/896234119 -This code repository contains the U.S. Reference Software Implementation of -Low Frequency / Medium Frequency (LF/MF) Propagation Model. This Python package wraps the -[base C++ implementation](https://github.com/NTIA/LFMF). +This code repository contains a Python wrapper for the NTIA/ITS implementation of the +Low Frequency / Medium Frequency (LF/MF) Propagation Model. LF/MF predicts basic transmission +loss in the frequency range 0.01 - 30 MHz for propagation paths over a smooth Earth and antenna +heights less than 50 meters. This Python package wraps the [NTIA/ITS C++ implementation](https://github.com/NTIA/LFMF). ## Getting Started ## -> [!NOTE] -> The text below indicates this package is distributed on PyPi, -> however it is not yet uploaded. A link will be provided here when available. - -This software is distributed on [PyPI](#) and is easily installable +This software is distributed on [PyPI](https://pypi.org/project/proplib-lfmf) and is easily installable using the following command. ```cmd -pip install LFMF +pip install proplib-lfmf ``` General information about using this model is available on @@ -79,16 +57,15 @@ library from C++ source code; see relevant build instructions [here](https://github.com/NTIA/LFMF?tab=readme-ov-file#configure-and-build). 1. Optionally, configure and activate a virtual environment using a tool such as -[`venv`](https://docs.python.org/3/library/venv.html) or +[`venv`](https://docs.python.org/3/library/venv.html) or [`conda`](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html). - -2. Clone the parent repository, then initialize the Git submodule containing the Python wrapper. This repository structure makes test data available to the Python wrapper. +1. Clone this repository, then initialize the Git submodule containing the test data. ```cmd # Clone the repository - git clone https://github.com/NTIA/LFMF - cd LFMF + git clone https://github.com/NTIA/LFMF-python + cd LFMF-python # Initialize Git submodule containing test data git submodule init @@ -97,22 +74,17 @@ library from C++ source code; see relevant build instructions git submodule update ``` -3. Compile the C++ library for your platform, following instructions [here](https://github.com/NTIA/LFMF?tab=readme-ov-file#configure-and-build). Following these instructions should automatically copy the shared library into the location required by the Python wrapper. - - **OR** - - Download the shared library (`.dll`, `.so`, or `.dylib`) from a +1. Download the shared library (`.dll`, `.so`, or `.dylib`) from a [GitHub Release](https://github.com/NTIA/LFMF/releases). Then place the downloaded file in `src/ITS/Propagation/LFMF/` (alongside `__init__.py`). - -4. Install the local package and development dependencies into your current environment: +1. Install the local package and development dependencies into your current environment: ```cmd pip install .[dev] ``` -5. To build the wheel for your platform: +1. To build the wheel for your platform: ```cmd hatchling build @@ -130,12 +102,15 @@ pytest ## References ## -LFMF-python: Update references - - [ITS Propagation Library Wiki](https://ntia.github.io/propagation-library-wiki) - [LFMF Wiki Page](https://ntia.github.io/propagation-library-wiki/models/LFMF) - [`ITS.Propagation.LFMF` C++ API Reference](https://ntia.github.io/LFMF) +- Bremmer, H. "Terrestrial Radio Waves" _Elsevier_, 1949. +- DeMinco, N. "Medium Frequency Propagation Prediction Techniques and Antenna Modeling for Intelligent Transportation Systems (ITS) Broadcast Applications", [_NTIA Report 99-368_](https://www.its.bldrdoc.gov/publications/2399.aspx), August 1999 +- DeMinco, N. "Ground-wave Analysis Model For MF Broadcast System", [_NTIA Report 86-203_](https://www.its.bldrdoc.gov/publications/2226.aspx), September 1986 +- Sommerfeld, A. "The propagation of waves in wireless telegraphy", _Ann. Phys._, 1909, 28, p.665 +- Wait, J. "Radiation From a Vertical Antenna Over a Curved Stratified Ground", _Journal of Research of the National Bureau of Standards_. Vol 56, No. 4, April 1956. Research Paper 2671 ## Contact ## -For technical questions, contact . \ No newline at end of file +For technical questions, contact . From 61a00493b9f47f5537c5fdff5f54c86124f1461c Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:44:02 -0500 Subject: [PATCH 48/57] Update pyproject.toml contents --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ee93b93..7ffe4d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,9 +3,9 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "LFMF" # LFMF-python update package name +name = "LFMF" dynamic = ["version"] -description = "Python wrapper for Low Frequency / Medium Frequency (LF/MF) Propagation Model" +description = "A Python wrapper for the NTIA/ITS implementation of the Low Frequency / Medium Frequency (LF/MF) Propagation Model" readme = "README.md" requires-python = ">=3.9" license = { file = "LICENSE.md" } From 93a43a89754d6015462575cd8bfc7d08adcb5d4b Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:49:27 -0500 Subject: [PATCH 49/57] Update CITATION.cff contents --- CITATION.cff | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index b1a5bb7..a4ce4c3 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,15 +4,22 @@ title: >- message: Please cite this software using these metadata. type: software authors: - - family-names: Kozma - given-names: William - name-suffix: Jr. + - family-names: Heroy + given-names: Chen affiliation: >- U.S. Department of Commerce, National Telecommunications and Information Administration, Institute for Telecommunication Sciences - orcid: 'https://orcid.org/0000-0002-7417-4009' - email: wkozma@ntia.gov + orcid: 'https://orcid.org/0009-0006-8728-4502' + email: cheroy.ctr@ntia.gov + - family-names: Romaniello + given-names: Anthony W. + affiliation: >- + U.S. Department of Commerce, National + Telecommunications and Information Administration, + Institute for Telecommunication Sciences + orcid: 'https://orcid.org/0000-0001-8437-6504' + email: aromaniello@ntia.gov - name: >- U.S. Department of Commerce, National Telecommunications and Information Administration, @@ -25,11 +32,11 @@ authors: alias: NTIA/ITS email: code@ntia.gov website: 'https://its.ntia.gov' -repository-code: 'https://github.com/NTIA/LFMF' +repository-code: 'https://github.com/NTIA/LFMF-python' url: 'https://ntia.github.io/propagation-library-wiki/models/LFMF' -repository: 'https://github.com/NTIA/LFMF' keywords: - its - propagation - lfmf -version: 1.0.0 + - antennas +version: 1.1.0 From 6aa300e14f68463523a070e9e05b62b172255971 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:53:23 -0500 Subject: [PATCH 50/57] Add and revise input parameter unit information --- src/ITS/Propagation/LFMF/LFMF.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ITS/Propagation/LFMF/LFMF.py b/src/ITS/Propagation/LFMF/LFMF.py index 5495b63..cc991b2 100644 --- a/src/ITS/Propagation/LFMF/LFMF.py +++ b/src/ITS/Propagation/LFMF/LFMF.py @@ -13,7 +13,7 @@ class Result(Structure): # Load the shared library -lib = PropLibCDLL("LFMF-1.0") +lib = PropLibCDLL("LFMF-1.1") # Define function prototypes lib.LFMF.restype = c_int @@ -36,15 +36,15 @@ def LFMF(h_tx__meter: float, h_rx__meter: float, f__mhz: float, P_tx__watt: floa """ Compute the Low Frequency / Medium Frequency (LF/MF) propagation prediction - :param h_tx__meter: Height of the transmitter, in meter - :param h_rx__meter: Height of the receiver, in meter + :param h_tx__meter: Height of the transmitter, in meters + :param h_rx__meter: Height of the receiver, in meters :param f__mhz: Frequency, in MHz - :param P_tx__watt: Transmitter power, in Watts + :param P_tx__watt: Transmitter power, in watts :param N_s: Surface refractivity, in N-Units - :param d__km: Path distance, in km - :param epsilon: Relative permittivity - :param sigma: Conductivity - :param pol: Polarization + :param d__km: Path distance, in kilometers + :param epsilon: Relative permittivity (dimensionless) + :param sigma: Conductivity, in siemens per meter + :param pol: Polarization (enum value) :raises ValueError: If any input parameter is not in its valid range. :raises Exception: If an unknown error is encountered. From 44b2bad127a1335cbbb9ec4cd878f90cb2b38a28 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:54:43 -0500 Subject: [PATCH 51/57] Double underscore before unit in output variable name --- src/ITS/Propagation/LFMF/LFMF.py | 2 +- tests/test_lfmf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ITS/Propagation/LFMF/LFMF.py b/src/ITS/Propagation/LFMF/LFMF.py index cc991b2..ee75c79 100644 --- a/src/ITS/Propagation/LFMF/LFMF.py +++ b/src/ITS/Propagation/LFMF/LFMF.py @@ -7,7 +7,7 @@ class Result(Structure): # C Struct for library outputs _fields_ = [('A_btl__db', c_double), - ('E_dBuVm', c_double), + ('E__dBuVm', c_double), ('P_rx__dbm', c_double), ('method', c_int)] diff --git a/tests/test_lfmf.py b/tests/test_lfmf.py index 14ce9fd..e6dcfb2 100644 --- a/tests/test_lfmf.py +++ b/tests/test_lfmf.py @@ -28,7 +28,7 @@ def test_lfmf(inputs, rtn, expected): if rtn == 0: result = LFMF.LFMF(*inputs) assert result.A_btl__db == pytest.approx(expected[0], abs=ABSTOL__DB) - assert result.E_dBuVm == pytest.approx(expected[1], abs=ABSTOL__DB) + assert result.E__dBuVm == pytest.approx(expected[1], abs=ABSTOL__DB) assert result.P_rx__dbm == pytest.approx(expected[2], abs=ABSTOL__DB) assert result.method == int(expected[3]) else: From 7bd5774a28a30002c6a0d6f4ec597560c5106d5c Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:55:16 -0500 Subject: [PATCH 52/57] Update version to 1.1.0 --- src/ITS/Propagation/LFMF/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ITS/Propagation/LFMF/__init__.py b/src/ITS/Propagation/LFMF/__init__.py index 3ec44d4..1af35eb 100644 --- a/src/ITS/Propagation/LFMF/__init__.py +++ b/src/ITS/Propagation/LFMF/__init__.py @@ -1,6 +1,6 @@ # Version X.Y.Z: X.Y is the version of the C++ source, # and Z is the version of this Python wrapper -__version__ = "1.0.0" +__version__ = "1.1.0" from .LFMF import * From 1b82f77074677353ea099c12aa990772a0dcb85b Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:57:36 -0500 Subject: [PATCH 53/57] Add test utils from template repository --- tests/test_lfmf.py | 17 +---------------- tests/test_utils.py | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 16 deletions(-) create mode 100644 tests/test_utils.py diff --git a/tests/test_lfmf.py b/tests/test_lfmf.py index e6dcfb2..db2d577 100644 --- a/tests/test_lfmf.py +++ b/tests/test_lfmf.py @@ -1,23 +1,8 @@ -import csv -from pathlib import Path - import pytest from ITS.Propagation import LFMF - -# Test data is expected to exist in parent repository tests/data -TEST_DATA_DIR = (Path(__file__).parent.parent.parent.parent / "tests") / "data" -ABSTOL__DB = 1.0E-1 # Absolute tolerance, in dB, to ensure outputs match expected value - - -def read_csv_test_data(filename: str): - with open(TEST_DATA_DIR / filename) as f: - reader = csv.reader(f) - next(reader) # Skip header row - for row in reader: - # yields (*inputs, rtn, *outputs) - yield tuple(map(float, row[:-5])), int(row[-5]), tuple(map(float, row[-4:])) +from .test_utils import ABSTOL__DB, read_csv_test_data @pytest.mark.parametrize( diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..b23066e --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,23 @@ +import csv +from pathlib import Path + +# Test data is expected to exist in tests/data +TEST_DATA_DIR = Path(__file__).parent / "data" +ABSTOL__DB = 0.1 # Absolute tolerance, in dB, to ensure outputs match expected value + +# Check if test data directory exists and is not empty +if not TEST_DATA_DIR.exists() or not any(TEST_DATA_DIR.iterdir()): + _test_data_checked = True + raise RuntimeError( + f"Test data is not available in {TEST_DATA_DIR}.\n Try running " + + "`git submodule init` and `git submodule update` to clone the test data submodule." + ) + + +def read_csv_test_data(filename: str): + with open(TEST_DATA_DIR / filename) as f: + reader = csv.reader(f) + next(reader) # Skip header row + for row in reader: + # yields (*inputs, rtn, *outputs) + yield tuple(map(float, row[:-5])), int(row[-5]), tuple(map(float, row[-4:])) From 0afc7985a07afbf2e6b0c1d14040840f5268c5c1 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:03:40 -0500 Subject: [PATCH 54/57] Add license and disclaimer information --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index dfb7b1f..8483437 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,16 @@ pytest - Sommerfeld, A. "The propagation of waves in wireless telegraphy", _Ann. Phys._, 1909, 28, p.665 - Wait, J. "Radiation From a Vertical Antenna Over a Curved Stratified Ground", _Journal of Research of the National Bureau of Standards_. Vol 56, No. 4, April 1956. Research Paper 2671 +## License ## + +See [LICENSE](./LICENSE.md). + +"Python" and the Python logos are trademarks or registered trademarks of the Python Software Foundation, used by the National Telecommunications and Information Administration with permission from the Foundation. + ## Contact ## For technical questions, contact . + +## Disclaimer ## + +Certain commercial equipment, instruments, or materials are identified in this project were used for the convenience of the developers. In no case does such identification imply recommendation or endorsement by the National Telecommunications and Information Administration, nor does it imply that the material or equipment identified is necessarily the best available for the purpose. From 577e654820b04b43467334897f7cdce6ebd3cd18 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:08:39 -0500 Subject: [PATCH 55/57] Add __init__.py to test directory --- tests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 From e83d52c11b9edbe725a08b957fc9dc259eba3148 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:09:22 -0500 Subject: [PATCH 56/57] run pre-commit hooks on all files --- src/ITS/Propagation/LFMF/LFMF.py | 45 ++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/ITS/Propagation/LFMF/LFMF.py b/src/ITS/Propagation/LFMF/LFMF.py index ee75c79..fa1e12e 100644 --- a/src/ITS/Propagation/LFMF/LFMF.py +++ b/src/ITS/Propagation/LFMF/LFMF.py @@ -6,10 +6,12 @@ class Result(Structure): # C Struct for library outputs - _fields_ = [('A_btl__db', c_double), - ('E__dBuVm', c_double), - ('P_rx__dbm', c_double), - ('method', c_int)] + _fields_ = [ + ("A_btl__db", c_double), + ("E__dBuVm", c_double), + ("P_rx__dbm", c_double), + ("method", c_int), + ] # Load the shared library @@ -18,21 +20,30 @@ class Result(Structure): # Define function prototypes lib.LFMF.restype = c_int lib.LFMF.argtypes = ( - c_double, - c_double, - c_double, - c_double, - c_double, - c_double, - c_double, - c_double, - c_int, - POINTER(Result), + c_double, + c_double, + c_double, + c_double, + c_double, + c_double, + c_double, + c_double, + c_int, + POINTER(Result), ) -def LFMF(h_tx__meter: float, h_rx__meter: float, f__mhz: float, P_tx__watt: float, - N_s: float, d__km: float, epsilon: float, sigma: float, pol: int) -> Result: +def LFMF( + h_tx__meter: float, + h_rx__meter: float, + f__mhz: float, + P_tx__watt: float, + N_s: float, + d__km: float, + epsilon: float, + sigma: float, + pol: int, +) -> Result: """ Compute the Low Frequency / Medium Frequency (LF/MF) propagation prediction @@ -63,7 +74,7 @@ def LFMF(h_tx__meter: float, h_rx__meter: float, f__mhz: float, P_tx__watt: floa c_double(epsilon), c_double(sigma), c_int(int(pol)), - byref(result) + byref(result), ) ) From 6907448fb8e21de8a10ccd60155245f932fe0f40 Mon Sep 17 00:00:00 2001 From: Anthony Romaniello <66272872+aromanielloNTIA@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:13:18 -0500 Subject: [PATCH 57/57] Update CFF validator for Ubuntu 24.04 runner --- .github/workflows/cff-validator.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/cff-validator.yml b/.github/workflows/cff-validator.yml index 83d75d0..6fce818 100644 --- a/.github/workflows/cff-validator.yml +++ b/.github/workflows/cff-validator.yml @@ -23,3 +23,5 @@ jobs: uses: actions/checkout@v4 - name: Validate CITATION.cff uses: dieghernan/cff-validator@v3 + with: + install-r: true