From c773b9b180b8afbe1a47d778ec551beac449ab23 Mon Sep 17 00:00:00 2001 From: Sebastian Brueckner <77582282+budschi@users.noreply.github.com> Date: Thu, 13 Jun 2024 08:18:12 +0000 Subject: [PATCH] Generated plugin from cookiecutter template --- .cruft.json | 26 +++ .github/workflows/actions.yml | 56 +++++ .github/workflows/cruft-update.yml | 75 ++++++ .github/workflows/mkdocs-deploy.yml | 24 ++ .gitignore | 130 +++++++++++ .vscode/settings.json | 21 ++ LICENSE | 213 ++---------------- MANIFEST.in | 1 + README.md | 133 ++++++----- docs/assets/.gitignore | 1 + docs/assets/favicon.png | Bin 0 -> 18325 bytes docs/assets/nomad-plugin-logo.png | Bin 0 -> 68578 bytes docs/explanation/explanation.md | 4 + .../how_to/contribute_to_the_documentation.md | 4 + docs/how_to/contribute_to_this_plugin.md | 5 + docs/how_to/install_this_plugin.md | 4 + docs/how_to/use_this_plugin.md | 10 + docs/index.md | 48 ++++ docs/reference/references.md | 4 + docs/stylesheets/extra.css | 69 ++++++ docs/theme/partials/header.html | 86 +++++++ docs/tutorial/tutorial.md | 4 + mkdocs.yml | 57 +++++ move_template_files.sh | 4 + pyproject.toml | 114 ++++++++++ requirements_docs.txt | 4 + src/nomad_ikz_raman/__init__.py | 0 src/nomad_ikz_raman/apps/__init__.py | 24 ++ src/nomad_ikz_raman/parsers/__init__.py | 18 ++ src/nomad_ikz_raman/parsers/myparser.py | 31 +++ .../schema_packages/__init__.py | 17 ++ .../schema_packages/mypackage.py | 38 ++++ tests/apps/test_app.py | 4 + tests/conftest.py | 0 tests/data/.gitkeep | 0 tests/data/example.out | 0 tests/data/test.archive.yaml | 3 + tests/parsers/test_parser.py | 12 + tests/schema_packages/test_schema.py | 11 + 39 files changed, 997 insertions(+), 258 deletions(-) create mode 100644 .cruft.json create mode 100644 .github/workflows/actions.yml create mode 100644 .github/workflows/cruft-update.yml create mode 100644 .github/workflows/mkdocs-deploy.yml create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 MANIFEST.in create mode 100644 docs/assets/.gitignore create mode 100644 docs/assets/favicon.png create mode 100644 docs/assets/nomad-plugin-logo.png create mode 100644 docs/explanation/explanation.md create mode 100644 docs/how_to/contribute_to_the_documentation.md create mode 100644 docs/how_to/contribute_to_this_plugin.md create mode 100644 docs/how_to/install_this_plugin.md create mode 100644 docs/how_to/use_this_plugin.md create mode 100644 docs/index.md create mode 100644 docs/reference/references.md create mode 100644 docs/stylesheets/extra.css create mode 100644 docs/theme/partials/header.html create mode 100644 docs/tutorial/tutorial.md create mode 100644 mkdocs.yml create mode 100644 move_template_files.sh create mode 100644 pyproject.toml create mode 100644 requirements_docs.txt create mode 100644 src/nomad_ikz_raman/__init__.py create mode 100644 src/nomad_ikz_raman/apps/__init__.py create mode 100644 src/nomad_ikz_raman/parsers/__init__.py create mode 100644 src/nomad_ikz_raman/parsers/myparser.py create mode 100644 src/nomad_ikz_raman/schema_packages/__init__.py create mode 100644 src/nomad_ikz_raman/schema_packages/mypackage.py create mode 100644 tests/apps/test_app.py create mode 100644 tests/conftest.py create mode 100644 tests/data/.gitkeep create mode 100644 tests/data/example.out create mode 100644 tests/data/test.archive.yaml create mode 100644 tests/parsers/test_parser.py create mode 100644 tests/schema_packages/test_schema.py diff --git a/.cruft.json b/.cruft.json new file mode 100644 index 0000000..6bba759 --- /dev/null +++ b/.cruft.json @@ -0,0 +1,26 @@ +{ + "template": "https://github.com/FAIRmat-NFDI/cookiecutter-nomad-plugin", + "commit": "dbf41935075d9057d69478db6eb9e7901bb44992", + "checkout": null, + "context": { + "cookiecutter": { + "full_name": "Sebastian Brueckner", + "email": "sebastian.brueckner@physik.hu-berlin.de", + "github_username": "budschi", + "plugin_name": "ikz_raman", + "module_name": "ikz_raman", + "short_description": "NOMAD plugin for Raman data from a Horiba LabRAM instrument", + "version": "0.1.0", + "license": "MIT", + "include_schema_package": true, + "include_normalizer": false, + "include_parser": true, + "include_app": true, + "_copy_without_render": [ + "*.html" + ], + "_template": "https://github.com/FAIRmat-NFDI/cookiecutter-nomad-plugin" + } + }, + "directory": null +} diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml new file mode 100644 index 0000000..544ec7a --- /dev/null +++ b/.github/workflows/actions.yml @@ -0,0 +1,56 @@ +name: install-and-test-workflow +on: [push] +jobs: + install-and-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: 3.9 + - name: Install dependencies + run: | + pip install --upgrade pip + pip install '.[dev]' --index-url https://gitlab.mpcdf.mpg.de/api/v4/projects/2187/packages/pypi/simple + pip install coverage coveralls + - name: Test with pytest + run: | + python -m coverage run -m pytest -sv + - name: Submit to coveralls + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + coveralls --service=github + build-and-install: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: 3.9 + - name: Build the package + run: | + pip install --upgrade pip + pip install build + python -m build --sdist + - name: Install the package + run: | + pip install dist/*.tar.gz --index-url https://gitlab.mpcdf.mpg.de/api/v4/projects/2187/packages/pypi/simple + ruff-linting: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: chartboost/ruff-action@v1 + with: + args: "check ." + # to enable auto-formatting check, uncomment the following lines below + # ruff-formatting: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - uses: chartboost/ruff-action@v1 + # with: + # args: "format . --check" diff --git a/.github/workflows/cruft-update.yml b/.github/workflows/cruft-update.yml new file mode 100644 index 0000000..ace73a7 --- /dev/null +++ b/.github/workflows/cruft-update.yml @@ -0,0 +1,75 @@ +# /.github/workflows/cruft-update.yml +name: Update repository with Cruft +permissions: + contents: write + pull-requests: write +on: + schedule: + - cron: "0 14 * * 1" # Every Monday at 2pm (UTC time) + workflow_dispatch: +jobs: + update: + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + include: + - add-paths: . + body: Use this to merge the changes to this repository. + branch: cruft/update + commit-message: "chore: accept new Cruft update" + title: New updates detected with Cruft + - add-paths: .cruft.json + body: Use this to reject the changes in this repository. + branch: cruft/reject + commit-message: "chore: reject new Cruft update" + title: Reject new updates detected with Cruft + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Install Cruft + run: pip3 install cruft + + - name: Check if update is available + continue-on-error: false + id: check + run: | + CHANGES=0 + if [ -f .cruft.json ]; then + if ! cruft check; then + CHANGES=1 + fi + else + echo "No .cruft.json file" + fi + + echo "has_changes=$CHANGES" >> "$GITHUB_OUTPUT" + + - name: Run update if available + if: steps.check.outputs.has_changes == '1' + run: | + git config --global user.email "you@example.com" + git config --global user.name "GitHub" + + cruft update --skip-apply-ask --refresh-private-variables + git restore --staged . + + - name: Create pull request + if: steps.check.outputs.has_changes == '1' + uses: peter-evans/create-pull-request@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + add-paths: ${{ matrix.add-paths }} + commit-message: ${{ matrix.commit-message }} + branch: ${{ matrix.branch }} + delete-branch: true + branch-suffix: timestamp + title: ${{ matrix.title }} + body: | + This is an autogenerated PR. ${{ matrix.body }} + + [Cruft](https://cruft.github.io/cruft/) has detected updates from the Cookiecutter repository. diff --git a/.github/workflows/mkdocs-deploy.yml b/.github/workflows/mkdocs-deploy.yml new file mode 100644 index 0000000..c46ff23 --- /dev/null +++ b/.github/workflows/mkdocs-deploy.yml @@ -0,0 +1,24 @@ +name: Deploy MkDocs Site + +on: + push: + branches: + - main # Triggers deployment on push to the main branch + +permissions: + contents: write + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Deploy docs + uses: mhausenblas/mkdocs-deploy-gh-pages@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CONFIG_FILE: mkdocs.yml + REQUIREMENTS: requirements_docs.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b1619d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,130 @@ +# 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/ +pip-wheel-metadata/ +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/ + +# 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 +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.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 + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +.pyenv + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0c8648f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,21 @@ +{ + "editor.rulers": [ + 90 + ], + "editor.renderWhitespace": "all", + "editor.tabSize": 4, + "files.trimTrailingWhitespace": true, + "[python]": { + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll": "explicit", + "source.organizeImports": "explicit" + }, + "editor.defaultFormatter": "charliermarsh.ruff" + }, + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true +} diff --git a/LICENSE b/LICENSE index 261eeb9..d37f73b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,22 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +The MIT License (MIT) - 1. Definitions. +Copyright (c) 2024 Sebastian Brueckner - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..b5ccc2d --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +recursive-include * nomad_plugin.yaml diff --git a/README.md b/README.md index fcf513e..b585afe 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,93 @@ -# nomad-plugin-template -A template repository for creating a repository with a NOMAD plugin package. +# nomad-ikz_raman +NOMAD plugin for Raman data from a Horiba LabRAM instrument -## Getting started +---- -1. Click on the `Use this template` button and create a new plugin repository. The form will ask you to fill out the name for the new plugin repository. +This `nomad`_ plugin was generated with `Cookiecutter`_ along with `@nomad`_'s `cookiecutter-nomad-plugin`_ template. -2. In the newly created repository, start a new Github Codespace and generate the plugin structure. -Run the following command to create a new NOMAD plugin project using cookiecutter-nomad-plugin: +### Install + +You should create a virtual environment. You will need the `nomad-lab` package (and `pytest`). +We recommend using Python 3.9. ```sh -cruft create https://github.com/FAIRmat-NFDI/cookiecutter-nomad-plugin +python3 -m venv .pyenv +source .pyenv/bin/activate +pip install --upgrade pip +pip install -e '.[dev]' --index-url https://gitlab.mpcdf.mpg.de/api/v4/projects/2187/packages/pypi/simple ``` -Cookiecutter prompts you for information regarding your plugin: - -```no-highlight -full_name [John Doe]: Citizen Kane -email [john.doe@physik.hu-berlin.de]: citizen@kane.de -github_username [foo]: kane -plugin_name [foobar]: awesome-tools -module_name [awesome_tools]: awesome_tools -short_description [NOMAD example template]: An awesome plugin for NOMAD -version [0.1.0]: -Select license: -1 - MIT -2 - BSD-3 -3 - GNU GPL v3.0+ -Choose from 1, 2, 3 [1]: 2 -include_schema_package [y/n] (y): y -include_normalizer [y/n] (y): n -include_parser [y/n] (y): y -include_app [y/n] (y): n - -INFO:post_gen_project:Initializing python for package - src -.. -INFO:post_gen_project:Remove temporary folder: licenses -INFO:post_gen_project:Remove temporary folder: macros -INFO:post_gen_project:Remove temporary folder: py_sources +**Note!** +Until we have an official pypi NOMAD release with the plugins functionality. Make +sure to include NOMAD's internal package registry (e.g. via `--index-url`). + +### Testing + +You can run automated tests with `pytest`: + +```sh +pytest -svx tests ``` +### Run linting + +```sh +ruff check . +``` +### Run auto-formatting +This is entirely optional. To add this as a check in github actions pipeline, uncomment the `ruff-formatting` step in `./github/workflows/actions.yaml`. -There you go - you just created a minimal NOMAD plugin: - -> [!NOTE] -> In the above prompt, we pressed `y` for schema_package and parser, this creates a python package with two plugin entry points: one for parser and one for schema_package. - -```no-highlight -nomad-awesome-tools/ -├── LICENSE -├── README.rst -├── pyproject.toml -├── move_template_files.sh -├── src -│ └── nomad_awesome_tools -│ ├── __init__.py -| ├── schema_packages -│ | ├── __init__.py -│ | └── plugin.py -| └── parsers -│ ├── __init__.py -│ └── plugin.py -| -├── tests -│ ├── conftest.py -│ └── test_awesome.py -└── MANIFEST.in +```sh +ruff format . ``` +### Developing a NOMAD plugin + +Follow the [guide](https://nomad-lab.eu/prod/v1/staging/docs/howto/plugins/plugins.html) on how to develop NOMAD plugins. + +### Build the python package -> [!NOTE] -> The project `nomad-awesome-tools` is created in a new directory, we have included a helper script to move all the files to the parent level of the repository. +The `pyproject.toml` file contains everything that is necessary to turn the project +into a pip installable python package. Run the python build tool to create a package distribution: + +``` +pip install build +python -m build --sdist +``` +You can install the package with pip: + +``` +pip install dist/nomad-ikz_raman-0.1.0 +``` + +Read more about python packages, `pyproject.toml`, and how to upload packages to PyPI +on the [PyPI documentation](https://packaging.python.org/en/latest/tutorials/packaging-projects/). + +### Documentation on Github pages + +To deploy documentation on Github pages, make sure to [enable GitHub pages via the repo settings](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-from-a-branch). + +To view the documentation locally, install the documentation related packages using: ```sh -sh CHANGE_TO_PLUGIN_NAME/move_template_files.sh +pip install -r requirements_docs.txt ``` -> [!IMPORTANT] -> The `CHANGE_TO_PLUGIN_NAME` should be substituted by the name of the plugin you've created. In the above case it'll be `sh nomad-awesome-tools/move_template_files.sh`. +Run the documentation server: +```sh +mkdocs serve +``` + +### Template update + +We use cruft to update the project based on template changes. A `cruft-update.yml` is included in Github workflows to automatically check for updates and create pull requests to apply updates. Follow the [instructions](https://github.blog/changelog/2022-05-03-github-actions-prevent-github-actions-from-creating-and-approving-pull-requests/) on how to enable Github Actions to create pull requests. + +To run the check for updates locally, follow the instructions on [`cruft` website](https://cruft.github.io/cruft/#updating-a-project). + +### License +Distributed under the terms of the `MIT`_ license, "nomad-ikz_raman" is free and open source software diff --git a/docs/assets/.gitignore b/docs/assets/.gitignore new file mode 100644 index 0000000..3881e38 --- /dev/null +++ b/docs/assets/.gitignore @@ -0,0 +1 @@ +nomad-oasis*.zip \ No newline at end of file diff --git a/docs/assets/favicon.png b/docs/assets/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..f84c78fd23b8bbe52af0fb9f085eeef9a787bd03 GIT binary patch literal 18325 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 literal 0 HcmV?d00001 diff --git a/docs/assets/nomad-plugin-logo.png b/docs/assets/nomad-plugin-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..149856c2461b034b737e4bdd9caefbab284e115e GIT binary patch literal 68578 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

_Bx%uXD`0CbA0J`1Sd=9 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%0DTAlwUln*!EmTsQ5(o0=qrs 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 literal 0 HcmV?d00001 diff --git a/docs/explanation/explanation.md b/docs/explanation/explanation.md new file mode 100644 index 0000000..a2035f6 --- /dev/null +++ b/docs/explanation/explanation.md @@ -0,0 +1,4 @@ +# Explanation + +!!! note "Attention" + TODO diff --git a/docs/how_to/contribute_to_the_documentation.md b/docs/how_to/contribute_to_the_documentation.md new file mode 100644 index 0000000..173dce1 --- /dev/null +++ b/docs/how_to/contribute_to_the_documentation.md @@ -0,0 +1,4 @@ +# Contribute to the documentation + +!!! note "Attention" + TODO diff --git a/docs/how_to/contribute_to_this_plugin.md b/docs/how_to/contribute_to_this_plugin.md new file mode 100644 index 0000000..48d405a --- /dev/null +++ b/docs/how_to/contribute_to_this_plugin.md @@ -0,0 +1,5 @@ +# Contribute to This Plugin + +!!! note "Attention" + TODO + diff --git a/docs/how_to/install_this_plugin.md b/docs/how_to/install_this_plugin.md new file mode 100644 index 0000000..2b45e0f --- /dev/null +++ b/docs/how_to/install_this_plugin.md @@ -0,0 +1,4 @@ +# Install This Plugin + +!!! note "Attention" + TODO diff --git a/docs/how_to/use_this_plugin.md b/docs/how_to/use_this_plugin.md new file mode 100644 index 0000000..ad93966 --- /dev/null +++ b/docs/how_to/use_this_plugin.md @@ -0,0 +1,10 @@ +# How to Use This Plugin + +This plugin can be used in a NOMAD Oasis installation. + +## Add This Plugin to Your NOMAD installation + +Read the [NOMAD plugin documentation](https://nomad-lab.eu/prod/v1/staging/docs/plugins/plugins.html#add-a-plugin-to-your-nomad) for all details on how to deploy the plugin on your NOMAD instance. + +!!! note "Attention" + TODO diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..7289444 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,48 @@ +# Welcome to the `nomad-ikz_raman` documentation + +NOMAD plugin for Raman data from a Horiba LabRAM instrument + +## Introduction + +!!! note "Attention" + TODO + +

+
+ +### Tutorial + +TODO + +- [Tutorial](tutorial/tutorial.md) + +
+
+ +### How-to guides + +How-to guides provide step-by-step instructions for a wide range of tasks, with the overarching topics: + +- [Install this plugin](how_to/install_this_plugin.md) +- [Use this plugin](how_to/use_this_plugin.md) +- [Contribute to this plugin](how_to/contribute_to_this_plugin.md) +- [Contribute to the documentation](how_to/contribute_to_the_documentation.md) + +
+ +
+ +### Explanation + +The explanation [section](explanation/explanation.md) provides background knowledge on this plugin. + +
+
+ +### Reference + +The reference [section](reference/references.md) includes all CLI commands and arguments, all configuration options, +the possible schema annotations and their arguments, and a glossary of used terms. + +
+
diff --git a/docs/reference/references.md b/docs/reference/references.md new file mode 100644 index 0000000..c199e70 --- /dev/null +++ b/docs/reference/references.md @@ -0,0 +1,4 @@ +# References + +!!! note "Attention" + TODO diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..321e087 --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,69 @@ + +.md-header__button.md-logo :where(img,svg) { + width: 100%; + height: 30px; +} + +.md-header, .md-header__inner { + background-color: #fff; + color: #2A4CDF; +} + +.md-header[data-md-state=shadow] { + box-shadow: 0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%); + transition: box-shadow 200ms linear; +} + +.md-header__inner { + height: 80px; +} + +.md-header__topic { + font-size: 24px; +} + +.md-footer { + background-color: #2A4CDF; +} + +.md-search__form:hover { + background-color: rgba(0,0,0,.13); +} + +.md-typeset h1 { + color: black; + font-weight: 700; +} + +.youtube { + position: relative; + width: 100%; + height: 0; + padding-bottom: 56.25%; +} + +.youtube iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.home-grid { + display: grid; + grid-template-columns: 1fr 1fr; + grid-column-gap: 24px; + row-gap: 24px; +} + +.home-grid div { + border-radius: 4px; + padding: 24px; + background-color: #f3e9d9; +} + +.home-grid h3 { + margin-top: 0; + font-weight: 700; +} \ No newline at end of file diff --git a/docs/theme/partials/header.html b/docs/theme/partials/header.html new file mode 100644 index 0000000..5b091f3 --- /dev/null +++ b/docs/theme/partials/header.html @@ -0,0 +1,86 @@ +{#- + This file was automatically generated - do not edit +-#} +{% set class = "md-header" %} +{% if "navigation.tabs.sticky" in features %} + {% set class = class ~ " md-header--lifted" %} +{% endif %} +
+ + {% if "navigation.tabs.sticky" in features %} + {% if "navigation.tabs" in features %} + {% include "partials/tabs.html" %} + {% endif %} + {% endif %} +
\ No newline at end of file diff --git a/docs/tutorial/tutorial.md b/docs/tutorial/tutorial.md new file mode 100644 index 0000000..a24d72a --- /dev/null +++ b/docs/tutorial/tutorial.md @@ -0,0 +1,4 @@ +# Tutorial + +!!! note "Attention" + TODO diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..a9a6a4d --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,57 @@ +site_name: nomad-ikz_raman +site_description: NOMAD plugin for Raman data from a Horiba LabRAM instrument +site_author: Sebastian Brueckner + +repo_url: https://github.com/budschi/nomad-ikz_raman + +nav: + - Home: index.md + - Tutorial: tutorial/tutorial.md + - How-to guides: + - Install this Plugin: how_to/install_this_plugin.md + - Use this Plugin: how_to/use_this_plugin.md + - Contribute to this plugin: how_to/contribute_to_this_plugin.md + - Contribute to the documentation: how_to/contribute_to_the_documentation.md + - Explanation: explanation/explanation.md + - Reference: reference/references.md +plugins: + - search +theme: + name: material + palette: + primary: "#2A4CDF" + accent: "#008A67" + font: + text: "Titillium Web" + logo: assets/nomad-plugin-logo.png + favicon: assets/favicon.png + features: + - navigation.instant + custom_dir: docs/theme +markdown_extensions: + - attr_list + - md_in_html + - admonition + - pymdownx.details + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences + - toc: + permalink: True + - pymdownx.arithmatex: + generic: true + - attr_list + - mkdocs-click + - pymdownx.extra +extra: + generator: false + homepage: https://nomad-lab.eu +use_directory_urls: false +extra_css: + - stylesheets/extra.css +extra_javascript: + - javascript.js + - https://polyfill.io/v3/polyfill.min.js?features=es6 + - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js diff --git a/move_template_files.sh b/move_template_files.sh new file mode 100644 index 0000000..761fd5a --- /dev/null +++ b/move_template_files.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +rsync -avh nomad-ikz_raman/ . +rm -rfv nomad-ikz_raman diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..c3f96f0 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,114 @@ +[build-system] +requires = ["setuptools>=61.0.0", "setuptools-scm>=8.0"] +build-backend = "setuptools.build_meta" + +[project] +classifiers = [ + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "License :: OSI Approved :: MIT License", +] +name = "nomad-ikz_raman" +description = "NOMAD plugin for Raman data from a Horiba LabRAM instrument" +version = "0.1.0" +readme = "README.rst" +requires-python = ">=3.9" +authors = [ + { name = "Sebastian Brueckner", email = "sebastian.brueckner@physik.hu-berlin.de" }, +] +maintainers = [ + { name = "Sebastian Brueckner", email = "sebastian.brueckner@physik.hu-berlin.de" }, +] +license = { file = "LICENSE" } +dependencies = ["nomad-lab>=1.2.2dev578"] + +[project.urls] +Repository = "https://github.com/budschi/nomad-ikz_raman" + +[project.optional-dependencies] +dev = ["ruff", "pytest", "structlog"] + +[tool.ruff] +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".mypy_cache", + ".nox", + ".pants.d", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "venv", +] + +# Same as Black. +line-length = 88 +indent-width = 4 + + +[tool.ruff.lint] +select = [ + # pycodestyle + "E", + # Pyflakes + "F", + # pyupgrade + "UP", + # isort + "I", + # pylint + "PL", +] + +ignore = [ + "F403", # 'from module import *' used; unable to detect undefined names +] + +fixable = ["ALL"] + +# Allow unused variables when underscore-prefixed. +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +# this is entirely optional, you can remove this if you wish to +[tool.ruff.format] +# use single quotes for strings. +quote-style = "single" + +# indent with spaces, rather than tabs. +indent-style = "space" + +# Like Black, respect magic trailing commas. +skip-magic-trailing-comma = false + +# Like Black, automatically detect the appropriate line ending. +line-ending = "auto" + +[tool.setuptools] +package-dir = { "" = "src" } + +[tool.setuptools.packages.find] +where = ["src"] + +[project.entry-points.'nomad.plugin'] +myparser = "nomad_ikz_raman.parsers:myparser" +mypackage = "nomad_ikz_raman.schema_packages:mypackage" + +myapp = "nomad_ikz_raman.apps:myapp" diff --git a/requirements_docs.txt b/requirements_docs.txt new file mode 100644 index 0000000..bacf1ed --- /dev/null +++ b/requirements_docs.txt @@ -0,0 +1,4 @@ +mkdocs +mkdocs-material==8.1.1 +pymdown-extensions +mkdocs-click diff --git a/src/nomad_ikz_raman/__init__.py b/src/nomad_ikz_raman/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/nomad_ikz_raman/apps/__init__.py b/src/nomad_ikz_raman/apps/__init__.py new file mode 100644 index 0000000..cfbc588 --- /dev/null +++ b/src/nomad_ikz_raman/apps/__init__.py @@ -0,0 +1,24 @@ +from nomad.config.models.plugins import AppEntryPoint +from nomad.config.models.ui import App, Column, Columns, FilterMenu, FilterMenus + + +myapp = AppEntryPoint( + name='MyApp', + description='App defined using the new plugin mechanism.', + app=App( + label='MyApp', + path='myapp', + category='simulation', + columns=Columns( + selected=['entry_id'], + options={ + 'entry_id': Column(), + }, + ), + filter_menus=FilterMenus( + options={ + 'material': FilterMenu(label='Material'), + } + ), + ), +) diff --git a/src/nomad_ikz_raman/parsers/__init__.py b/src/nomad_ikz_raman/parsers/__init__.py new file mode 100644 index 0000000..c0024b9 --- /dev/null +++ b/src/nomad_ikz_raman/parsers/__init__.py @@ -0,0 +1,18 @@ +from nomad.config.models.plugins import ParserEntryPoint +from pydantic import Field + + +class MyParserEntryPoint(ParserEntryPoint): + parameter: int = Field(0, description='Custom configuration parameter') + + def load(self): + from nomad_ikz_raman.parsers.myparser import MyParser + + return MyParser(**self.dict()) + + +myparser = MyParserEntryPoint( + name='MyParser', + description='Parser defined using the new plugin mechanism.', + mainfile_name_re='.*\.myparser', +) diff --git a/src/nomad_ikz_raman/parsers/myparser.py b/src/nomad_ikz_raman/parsers/myparser.py new file mode 100644 index 0000000..c39e423 --- /dev/null +++ b/src/nomad_ikz_raman/parsers/myparser.py @@ -0,0 +1,31 @@ +from typing import ( + TYPE_CHECKING, +) + +if TYPE_CHECKING: + from nomad.datamodel.datamodel import ( + EntryArchive, + ) + from structlog.stdlib import ( + BoundLogger, + ) + +from nomad.config import config +from nomad.datamodel.results import Material, Results +from nomad.parsing.parser import MatchingParser + +configuration = config.get_plugin_entry_point( + 'nomad_ikz_raman.parsers:myparser' +) + + +class MyParser(MatchingParser): + def parse( + self, + mainfile: str, + archive: 'EntryArchive', + logger: 'BoundLogger', + child_archives: dict[str, 'EntryArchive'] = None, + ) -> None: + logger.info('MyParser.parse', parameter=configuration.parameter) + archive.results = Results(material=Material(elements=['H', 'O'])) diff --git a/src/nomad_ikz_raman/schema_packages/__init__.py b/src/nomad_ikz_raman/schema_packages/__init__.py new file mode 100644 index 0000000..0fec924 --- /dev/null +++ b/src/nomad_ikz_raman/schema_packages/__init__.py @@ -0,0 +1,17 @@ +from nomad.config.models.plugins import SchemaPackageEntryPoint +from pydantic import Field + + +class MySchemaPackageEntryPoint(SchemaPackageEntryPoint): + parameter: int = Field(0, description='Custom configuration parameter') + + def load(self): + from nomad_ikz_raman.schema_packages.mypackage import m_package + + return m_package + + +mypackage = MySchemaPackageEntryPoint( + name='MyPackage', + description='Schema package defined using the new plugin mechanism.', +) diff --git a/src/nomad_ikz_raman/schema_packages/mypackage.py b/src/nomad_ikz_raman/schema_packages/mypackage.py new file mode 100644 index 0000000..49c16e1 --- /dev/null +++ b/src/nomad_ikz_raman/schema_packages/mypackage.py @@ -0,0 +1,38 @@ +from typing import ( + TYPE_CHECKING, +) + +if TYPE_CHECKING: + from nomad.datamodel.datamodel import ( + EntryArchive, + ) + from structlog.stdlib import ( + BoundLogger, + ) + +from nomad.config import config +from nomad.datamodel.data import Schema +from nomad.datamodel.metainfo.annotations import ELNAnnotation, ELNComponentEnum +from nomad.metainfo import Quantity, SchemaPackage + +configuration = config.get_plugin_entry_point( + 'nomad_ikz_raman.schema_packages:mypackage' +) + +m_package = SchemaPackage() + + +class MySchema(Schema): + name = Quantity( + type=str, a_eln=ELNAnnotation(component=ELNComponentEnum.StringEditQuantity) + ) + message = Quantity(type=str) + + def normalize(self, archive: 'EntryArchive', logger: 'BoundLogger') -> None: + super().normalize(archive, logger) + + logger.info('MySchema.normalize', parameter=configuration.parameter) + self.message = f'Hello {self.name}!' + + +m_package.__init_metainfo__() diff --git a/tests/apps/test_app.py b/tests/apps/test_app.py new file mode 100644 index 0000000..40824fa --- /dev/null +++ b/tests/apps/test_app.py @@ -0,0 +1,4 @@ +def test_importing_app(): + # this will raise an exception if pydantic model validation fails for th app + from nomad_ikz_raman.apps import myapp + diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/data/.gitkeep b/tests/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/data/example.out b/tests/data/example.out new file mode 100644 index 0000000..e69de29 diff --git a/tests/data/test.archive.yaml b/tests/data/test.archive.yaml new file mode 100644 index 0000000..3d07c0b --- /dev/null +++ b/tests/data/test.archive.yaml @@ -0,0 +1,3 @@ +data: + m_def: nomad_ikz_raman.schema_packages.mypackage.MySchema + name: Markus diff --git a/tests/parsers/test_parser.py b/tests/parsers/test_parser.py new file mode 100644 index 0000000..e677d55 --- /dev/null +++ b/tests/parsers/test_parser.py @@ -0,0 +1,12 @@ +import logging + +from nomad.datamodel import EntryArchive +from nomad_ikz_raman.parsers.myparser import MyParser + + +def test_parse_file(): + parser = MyParser() + archive = EntryArchive() + parser.parse('tests/data/example.out', archive, logging.getLogger()) + + assert archive.results.material.elements == ['H', 'O'] diff --git a/tests/schema_packages/test_schema.py b/tests/schema_packages/test_schema.py new file mode 100644 index 0000000..76210db --- /dev/null +++ b/tests/schema_packages/test_schema.py @@ -0,0 +1,11 @@ +import os.path + +from nomad.client import normalize_all, parse + + +def test_schema(): + test_file = os.path.join('tests', 'data', 'test.archive.yaml') + entry_archive = parse(test_file)[0] + normalize_all(entry_archive) + + assert entry_archive.data.message == 'Hello Markus!'