diff --git a/.cruft.json b/.cruft.json new file mode 100644 index 0000000..7eccb65 --- /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": "Lauri Himanen", + "email": "lauri.himanen@physik.hu-berlin.de", + "github_username": "lauri-codes", + "plugin_name": "bayesian-optimization", + "module_name": "bayesian_optimization", + "short_description": "NOMAD plugin for driving experiments/simulations using bayesian optimization", + "version": "0.1.0", + "license": "Apache Software License 2.0", + "include_schema_package": true, + "include_normalizer": false, + "include_parser": false, + "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..427417b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,4 @@ + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -178,7 +179,7 @@ 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 "[]" + 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 @@ -186,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + 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. 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..b8ded12 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-bayesian-optimization +NOMAD plugin for driving experiments/simulations using bayesian optimization -## 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-bayesian-optimization-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 `Apache Software License 2.0`_ license, "nomad-bayesian-optimization" 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 0000000..f84c78f Binary files /dev/null and b/docs/assets/favicon.png differ diff --git a/docs/assets/nomad-plugin-logo.png b/docs/assets/nomad-plugin-logo.png new file mode 100644 index 0000000..149856c Binary files /dev/null and b/docs/assets/nomad-plugin-logo.png differ 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..7a3814a --- /dev/null +++ b/docs/index.md @@ -0,0 +1,48 @@ +# Welcome to the `nomad-bayesian-optimization` documentation + +NOMAD plugin for driving experiments/simulations using bayesian optimization + +## 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..979ad69 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,57 @@ +site_name: nomad-bayesian-optimization +site_description: NOMAD plugin for driving experiments/simulations using bayesian optimization +site_author: Lauri Himanen + +repo_url: https://github.com/lauri-codes/nomad-bayesian-optimization + +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..bd3bd0d --- /dev/null +++ b/move_template_files.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +rsync -avh nomad-bayesian-optimization/ . +rm -rfv nomad-bayesian-optimization diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..5ed2803 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,116 @@ +[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 :: Apache Software License", +] +name = "nomad-bayesian-optimization" +description = "NOMAD plugin for driving experiments/simulations using bayesian optimization" +version = "0.1.0" +readme = "README.rst" +requires-python = ">=3.9" +authors = [ + { name = "Lauri Himanen", email = "lauri.himanen@physik.hu-berlin.de" }, +] +maintainers = [ + { name = "Lauri Himanen", email = "lauri.himanen@physik.hu-berlin.de" }, +] +license = { file = "LICENSE" } +dependencies = [ + "nomad-lab>=1.2.2dev578", + "baybe", + "structlog", +] + +[project.urls] +Repository = "https://github.com/lauri-codes/nomad-bayesian-optimization" + +[project.optional-dependencies] +dev = ["ruff", "pytest"] + +[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'] +experiments = "nomad_bayesian_optimization.schema_packages:experiments" +bayesian_optimization = "nomad_bayesian_optimization.schema_packages:bayesian_optimization" 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_bayesian_optimization/__init__.py b/src/nomad_bayesian_optimization/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/nomad_bayesian_optimization/apps/__init__.py b/src/nomad_bayesian_optimization/apps/__init__.py new file mode 100644 index 0000000..cfbc588 --- /dev/null +++ b/src/nomad_bayesian_optimization/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_bayesian_optimization/example_uploads/__init__.py b/src/nomad_bayesian_optimization/example_uploads/__init__.py new file mode 100644 index 0000000..a05ef8e --- /dev/null +++ b/src/nomad_bayesian_optimization/example_uploads/__init__.py @@ -0,0 +1,24 @@ +from nomad.config.models.plugins import AppEntryPoint +from nomad.config.models.ui import App, Column, Columns, FilterMenu, FilterMenus + + +myexampleupload = 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_bayesian_optimization/example_uploads/getting_started/archive.json b/src/nomad_bayesian_optimization/example_uploads/getting_started/archive.json new file mode 100644 index 0000000..e89bd35 --- /dev/null +++ b/src/nomad_bayesian_optimization/example_uploads/getting_started/archive.json @@ -0,0 +1,942 @@ +{ + "data": { + "m_def": "nomad_bayesian_optimization.schema_packages.bayesian_optimization.BayesianOptimization", + "optimization": "gASVvwMAAAAAAACMEXBhbmRhcy5jb3JlLmZyYW1llIwJRGF0YUZyYW1llJOUKYGUfZQojARfbWdylIwecGFuZGFzLmNvcmUuaW50ZXJuYWxzLm1hbmFnZXJzlIwMQmxvY2tNYW5hZ2VylJOUKIwWcGFuZGFzLl9saWJzLmludGVybmFsc5SMD191bnBpY2tsZV9ibG9ja5STlIwVbnVtcHkuY29yZS5tdWx0aWFycmF5lIwMX3JlY29uc3RydWN0lJOUjAVudW1weZSMB25kYXJyYXmUk5RLAIWUQwFilIeUUpQoSwFLAUsBhpRoD4wFZHR5cGWUk5SMAk84lImIh5RSlChLA4wBfJROTk5K/////0r/////Sz90lGKJXZSMB1NpbGljb26UYXSUYowIYnVpbHRpbnOUjAVzbGljZZSTlEsASwFLAYeUUpRLAoeUUpRoC2gOaBFLAIWUaBOHlFKUKEsBSwNLAYaUaBiMAmY4lImIh5RSlChLA4wBPJROTk5K/////0r/////SwB0lGKJQxgL2B0UJzZ/QFfdIlBVafc/4aCIaXfX/D+UdJRiaCNLAUsESwGHlFKUSwKHlFKUaAtoDmgRSwCFlGgTh5RSlChLAUsBSwGGlGgYjAJpOJSJiIeUUpQoSwNoL05OTkr/////Sv////9LAHSUYolDCAEAAAAAAAAAlHSUYmgjSwRLBUsBh5RSlEsCh5RSlGgLaA5oEUsAhZRoE4eUUpQoSwFLAUsBhpRoLolDCAAAAAAAAPh/lHSUYmgjSwVLBksBh5RSlEsCh5RSlHSUXZQojBhwYW5kYXMuY29yZS5pbmRleGVzLmJhc2WUjApfbmV3X0luZGV4lJOUaFGMBUluZGV4lJOUfZQojARkYXRhlGgOaBFLAIWUaBOHlFKUKEsBSwaFlGgbiV2UKIwJc3Vic3RyYXRllIwLdGVtcGVyYXR1cmWUjA1nYXNfZmxvd19yYXRllIwQcmVmcmFjdGl2ZV9pbmRleJSMB0JhdGNoTnKUjAVGaXROcpRldJRijARuYW1llE51hpRSlGhTjBlwYW5kYXMuY29yZS5pbmRleGVzLnJhbmdllIwKUmFuZ2VJbmRleJSTlH2UKGhkTowFc3RhcnSUSwCMBHN0b3CUSwGMBHN0ZXCUSwF1hpRSlGWGlFKUjARfdHlwlIwJZGF0YWZyYW1llIwJX21ldGFkYXRhlF2UjAVhdHRyc5R9lIwGX2ZsYWdzlH2UjBdhbGxvd3NfZHVwbGljYXRlX2xhYmVsc5SIc3ViLg==", + "figures": [ + { + "label": "Optimization results", + "figure": { + "data": [ + { + "hovertemplate": "x=%{x}
y=%{y}", + "legendgroup": "", + "marker": { + "color": "#636efa", + "symbol": "circle" + }, + "mode": "markers", + "name": "", + "orientation": "v", + "showlegend": false, + "x": [ + NaN + ], + "xaxis": "x", + "y": [ + 1.802604114762339 + ], + "yaxis": "y", + "type": "scatter" + } + ], + "layout": { + "template": { + "data": { + "histogram2dcontour": [ + { + "type": "histogram2dcontour", + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ] + } + ], + "choropleth": [ + { + "type": "choropleth", + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + ], + "histogram2d": [ + { + "type": "histogram2d", + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ] + } + ], + "heatmap": [ + { + "type": "heatmap", + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ] + } + ], + "heatmapgl": [ + { + "type": "heatmapgl", + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ] + } + ], + "contourcarpet": [ + { + "type": "contourcarpet", + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + ], + "contour": [ + { + "type": "contour", + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ] + } + ], + "surface": [ + { + "type": "surface", + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ] + } + ], + "mesh3d": [ + { + "type": "mesh3d", + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "parcoords": [ + { + "type": "parcoords", + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + } + ], + "scatterpolargl": [ + { + "type": "scatterpolargl", + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + } + ], + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "scattergeo": [ + { + "type": "scattergeo", + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + } + ], + "scatterpolar": [ + { + "type": "scatterpolar", + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "scattergl": [ + { + "type": "scattergl", + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + } + ], + "scatter3d": [ + { + "type": "scatter3d", + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + } + ], + "scattermapbox": [ + { + "type": "scattermapbox", + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + } + ], + "scatterternary": [ + { + "type": "scatterternary", + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + } + ], + "scattercarpet": [ + { + "type": "scattercarpet", + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ] + }, + "layout": { + "autotypenumbers": "strict", + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "hovermode": "closest", + "hoverlabel": { + "align": "left" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "bgcolor": "#E5ECF6", + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "ternary": { + "bgcolor": "#E5ECF6", + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "sequential": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ], + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ] + }, + "xaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "automargin": true, + "zerolinewidth": 2 + }, + "yaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "automargin": true, + "zerolinewidth": 2 + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white", + "gridwidth": 2 + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white", + "gridwidth": 2 + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white", + "gridwidth": 2 + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "geo": { + "bgcolor": "white", + "landcolor": "#E5ECF6", + "subunitcolor": "white", + "showland": true, + "showlakes": true, + "lakecolor": "white" + }, + "title": { + "x": 0.05 + }, + "mapbox": { + "style": "light" + } + } + }, + "xaxis": { + "anchor": "y", + "domain": [ + 0.0, + 0.45 + ] + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0.0, + 1.0 + ] + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.55, + 1.0 + ] + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0.0, + 1.0 + ], + "matches": "y", + "showticklabels": false + }, + "title": { + "text": "Optimization results" + }, + "height": 400, + "width": 716 + } + } + } + ], + "searchspace": { + "discrete": { + "parameters": [ + { + "type": "CategoricalParameter", + "name": "substrate", + "values": [ + "Silicon carbide", + "Silicon", + "Gallium nitride" + ], + "encoding": "OHE" + } + ] + }, + "continuous": { + "parameters": [ + { + "type": "NumericalContinuousParameter", + "name": "temperature", + "bounds": { + "lower": "300.0", + "upper": "600.0" + } + }, + { + "type": "NumericalContinuousParameter", + "name": "gas_flow_rate", + "bounds": { + "lower": "0.2", + "upper": "5.0" + } + } + ] + } + }, + "objective": { + "type": "SingleTargetObjective", + "target": { + "type": "NumericalTarget", + "name": "refractive_index", + "mode": "MATCH", + "transformation": "BELL", + "bounds": { + "lower": "2.4473", + "upper": "2.8473" + } + } + }, + "recommender": { + "type": "TwoPhaseMetaRecommender" + } + }, + "results": {} +} \ No newline at end of file diff --git a/src/nomad_bayesian_optimization/example_uploads/getting_started/example.py b/src/nomad_bayesian_optimization/example_uploads/getting_started/example.py new file mode 100644 index 0000000..b959073 --- /dev/null +++ b/src/nomad_bayesian_optimization/example_uploads/getting_started/example.py @@ -0,0 +1,146 @@ +api_url = '' +schema_name = 'nomad_bayesian_optimization.schema_packages.experiments.CVDExperiment' + +# ====================================================================================== +# Define the seach space +from baybe.parameters import CategoricalParameter, NumericalContinuousParameter +from baybe.searchspace import SearchSpace + +parameters = [ + CategoricalParameter( + name='substrate', + values=['Silicon carbide', 'Silicon', 'Gallium nitride'], + encoding='OHE', # one-hot encoding of categories + ), + NumericalContinuousParameter( + name='temperature', + bounds=(300, 600), + ), + NumericalContinuousParameter( + name='gas_flow_rate', + bounds=(0.2, 5), + ), +] + +searchspace = SearchSpace.from_product(parameters) + +# ====================================================================================== +# Define the optimization target +from baybe.objectives import SingleTargetObjective +from baybe.targets import NumericalTarget + +refractive_index_target = 2.6473 +refractive_index_sigma = 0.2 +target = NumericalTarget( + name='refractive_index', + mode='MATCH', + bounds=( + refractive_index_target - refractive_index_sigma, + refractive_index_target + refractive_index_sigma, + ), + transformation='BELL', +) +objective = SingleTargetObjective(target=target) + +# ====================================================================================== +# Define the acquisition strategy +from baybe.recommenders import SequentialGreedyRecommender, TwoPhaseMetaRecommender + +recommender = TwoPhaseMetaRecommender( + recommender=SequentialGreedyRecommender( + hybrid_sampler='Farthest', sampling_percentage=0.3 + ), +) + +# ====================================================================================== +# Prepare upload to store the generated data + +# ====================================================================================== +# Start optimization loop +import time + +import numpy as np +from baybe import Campaign + +from nomad_bayesian_optimization.schema_packages.experiments import CVDExperiment + +campaign = Campaign(searchspace, objective, recommender) + + +def get_samples(recommendations): + """In this function you can decide how the actual experiment/simulation is + performed. There are several alternatives: + + - Maybe you can control measurement devices directly through API calls. + - Maybe you create a loop that waits until someone manually inserts the + experiment results into NOMAD, and then query the results from it using + the NOMAD API. + - Maybe you run a simulation in this notebook + - Maybe you run a simulation using an HPC batch system + + In this example, we will create entries by sampling from a + fake model. + """ + for _, row in recommendations.iterrows(): + cvd_experiment = CVDExperiment().m_from_dict(row.to_dict()) + temp_mu = 400 + temp_sigma = 200 + gas_flow_mu = 2 + gas_flow_sigma = 3 + ideal_substrate = 'Silicon carbide' + refractive_index = float( + 2.6473 + * np.exp(-((cvd_experiment.temperature.m - temp_mu) ** 2 / temp_sigma**2)) + * np.exp( + -( + (cvd_experiment.gas_flow_rate.m - gas_flow_mu) ** 2 + / gas_flow_sigma**2 + ) + ) + ) + if cvd_experiment.substrate != ideal_substrate: + refractive_index *= 0.9 + cvd_experiment.refractive_index = refractive_index + time.sleep(2) + return cvd_experiment + + +i = 0 +result = 0 +threshold = 1 +while abs(refractive_index_target - result) > threshold: + df = campaign.recommend(batch_size=1) + print('New recommendation:') + print(df) + print('Testing recommendation...') + archive = get_samples(df) + print('Testing finished!') + result = archive.refractive_index + df['refractive_index'] = [result] + campaign.add_measurements(df) + i += 1 + +# At the end of the run, lets store the whole optimization run into an entry +import json + +from nomad.datamodel import EntryArchive + +from nomad_bayesian_optimization.schema_packages.bayesian_optimization import ( + BayesianOptimization, +) + +archive = EntryArchive() +bopt = BayesianOptimization.from_baybe_campaign(campaign) +archive.data = bopt +bopt.normalize(archive, None) + +with open('archive.json', 'w') as fout: + json.dump(archive.m_to_dict(), fout, indent=2) +# print(bopt.search_space) +# campaign_dict = campaign.to_dict() +# recommendation = deserialize_dataframe(campaign_dict['_cached_recommendation']) +# measurements = deserialize_dataframe(campaign_dict['_measurements_exp']) +# print(measurements) +# with open("campaign.json", 'w') as fout: +# json.dump(fout, campaign.to_dict()) +# print(f'Optimal refractive index {result} found after {i} loops') diff --git a/src/nomad_bayesian_optimization/example_uploads/getting_started/tutorial.ipynb b/src/nomad_bayesian_optimization/example_uploads/getting_started/tutorial.ipynb new file mode 100644 index 0000000..ca25e27 --- /dev/null +++ b/src/nomad_bayesian_optimization/example_uploads/getting_started/tutorial.ipynb @@ -0,0 +1,262 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "\n", + "