diff --git a/.dockerignore b/.dockerignore index 4ca4d01cd13d2ccee8949d845da1dd9092f93545..404e70e02e1f2ad5669981a6c82aeaa295ab422c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,7 +3,7 @@ **/.mypy_cache **/__pycache__ **/*.pyc -**/NOMAD.egg-info +**/*.egg-info .*env/ .pyenv*/ .pytest_cache @@ -14,6 +14,8 @@ **/.ipynb_checkpoints **/.volumes +nomad_lab.egg-info/ + data/ local/ target/ @@ -30,6 +32,7 @@ docs/*.graffle nomad/normalizing/data/*.db nomad/normalizing/data/*.msg +nomad/app/static nomad.yaml gui/node_modules/ diff --git a/.gitignore b/.gitignore index f3bb4173b26ab38ae2df734eeaef1460da698122..9d2c38aca1d3a1e1ca604f278370798a68926e7f 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,4 @@ parser.osio.log gui/src/metainfo.json gui/src/searchQuantities.json examples/workdir/ - +gunicorn.log.conf diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b74751f8dbcc44c921348be94c53f9ee7138ddca..236635717d95fb99b27e1d58229b043e10cae014 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,10 +9,11 @@ image: gitlab-registry.mpcdf.mpg.de/nomad-lab/nomad-fair/ci-runner # services: # - docker:dind +# TODO remove CI_NOMAD_DEV_PROXY + stages: - build - test - - deploy - release @@ -40,7 +41,7 @@ build: - /^dev-.*$/ - tags -linting: +python linting: stage: test image: $TEST_IMAGE script: @@ -55,13 +56,13 @@ linting: - $CI_COMMIT_REF_NAME =~ /^dev-.*$/ - $CI_COMMIT_MESSAGE =~ /\[skip[ _-]tests?\]/i -gui_linting: +gui linting: stage: test image: node script: - cd gui - yarn - - yarn run eslint 'src/**/*.js' + - yarn run lint except: refs: - tags @@ -69,7 +70,7 @@ gui_linting: - $CI_COMMIT_REF_NAME =~ /^dev-.*$/ - $CI_COMMIT_MESSAGE =~ /\[skip[ _-]tests?\]/i -tests: +python tests: stage: test image: $TEST_IMAGE services: @@ -100,7 +101,21 @@ tests: - $CI_COMMIT_REF_NAME =~ /^dev-.*$/ - $CI_COMMIT_MESSAGE =~ /\[skip[ _-]tests?\]/i -install_tests: +gui tests: + stage: test + image: node + script: + - cd gui + - yarn + - yarn run test + except: + refs: + - tags + variables: + - $CI_COMMIT_REF_NAME =~ /^dev-.*$/ + - $CI_COMMIT_MESSAGE =~ /\[skip[ _-]tests?\]/i + +install tests: stage: test image: python:3.7 before_script: @@ -124,7 +139,7 @@ install_tests: - $CI_COMMIT_REF_NAME =~ /^dev-.*$/ - $CI_COMMIT_MESSAGE =~ /\[skip[ _-]tests?\]/i -dev_setup_tests: +dev setup tests: stage: test image: python:3.7 script: @@ -138,23 +153,36 @@ dev_setup_tests: - $CI_COMMIT_REF_NAME =~ /^dev-.*$/ - $CI_COMMIT_MESSAGE =~ /\[skip[ _-]tests?\]/i -deploy: - stage: deploy +deploy dev: + stage: release before_script: - mkdir -p /etc/deploy - echo ${CI_K8S_CONFIG} | base64 -d > ${KUBECONFIG} script: - RELEASE_NAME=`echo ${CI_COMMIT_REF_NAME} | sed -e 's/[^A-Za-z0-9\-]/-/g'` - helm dependency update ops/helm/nomad - - helm upgrade --namespace nomad --install $RELEASE_NAME ops/helm/nomad -f ops/helm/nomad/ci-dev-values.yaml --set proxy.external.path=/dev/nomad/$RELEASE_NAME,image.tag=$CI_COMMIT_REF_NAME,roll=true --wait + - helm upgrade --namespace nomad --install $RELEASE_NAME ops/helm/nomad -f ops/helm/nomad/deployments/dev-values.yaml --set proxy.external.path=/dev/nomad/$RELEASE_NAME,image.tag=$CI_COMMIT_REF_NAME,roll=true --wait - docker pull $TEST_IMAGE - - docker run -t -e NOMAD_KEYCLOAK_REALM_NAME=fairdi_nomad_prod $TEST_IMAGE python -m nomad.cli client -n $CI_DEV_CLUSTER_PROXY/dev/nomad/$RELEASE_NAME/api -u admin -w $CI_NOMAD_ADMIN_PASSWORD integrationtests + - docker run -t -e NOMAD_KEYCLOAK_REALM_NAME=fairdi_nomad_prod $TEST_IMAGE python -m nomad.cli client -n https://nomad-lab.eu/dev/nomad/$RELEASE_NAME/api -u test -w $CI_NOMAD_TEST_PASSWORD integrationtests --skip-publish --skip-doi + except: + - /^dev-.*$/ + when: manual +deploy prod beta: + stage: release + before_script: + - mkdir -p /etc/deploy + - echo ${CI_K8S_PROD_CONFIG} | base64 -d > ${KUBECONFIG} + script: + - helm dependency update ops/helm/nomad + - helm upgrade --install nomad-prod-test ops/helm/nomad -f ops/helm/nomad/deployments/prod-beta-values.yaml --set image.tag=$CI_COMMIT_REF_NAME,roll=true --wait + - docker pull $TEST_IMAGE + - docker run -t -e NOMAD_KEYCLOAK_REALM_NAME=fairdi_nomad_prod $TEST_IMAGE python -m nomad.cli client -n https://nomad-lab.eu/prod/rae/beta/api -u test -w $CI_NOMAD_TEST_PASSWORD integrationtests --skip-publish --skip-doi except: - /^dev-.*$/ when: manual -release: +release latest image: stage: release script: - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN gitlab-registry.mpcdf.mpg.de @@ -164,10 +192,8 @@ release: except: - /^dev-.*$/ when: manual - only: - - branches -release_version: +release stable image: stage: release script: - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN gitlab-registry.mpcdf.mpg.de @@ -176,24 +202,26 @@ release_version: - docker push $LATEST_IMAGE - docker tag $TEST_IMAGE $STABLE_IMAGE - docker push $STABLE_IMAGE + when: manual only: - tags -release_pypi: +python package: stage: release - image: python:3.7 - before_script: - - git submodule sync - - git submodule update --init --jobs=4 script: - - pip install --upgrade pip - - pip install fastentrypoints - - pip install pyyaml - - pip install numpy - - pip install twine - - python setup.py compile - - python setup.py sdist - - python -m twine upload -u $CI_TWINE_USER -p $CI_TWINE_PASSWORD dist/* + - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN gitlab-registry.mpcdf.mpg.de + - docker pull $TEST_IMAGE + - docker run --rm $TEST_IMAGE python -m twine upload -u gitlab-ci-token -p ${CI_JOB_TOKEN} --repository-url https://gitlab.mpcdf.mpg.de/api/v4/projects/${CI_PROJECT_ID}/packages/pypi dist/nomad-lab.tar.gz + except: + - /^dev-.*$/ + when: manual + +pypi package: + stage: release + script: + - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN gitlab-registry.mpcdf.mpg.de + - docker pull $TEST_IMAGE + - docker run --rm $TEST_IMAGE python -m twine upload -u $CI_TWINE_USER -p $CI_TWINE_PASSWORD dist/nomad-lab.tar.gz when: manual only: - tags diff --git a/.gitmodules b/.gitmodules index 5116f7d319cf07c38ab54b7f2fb8b60f5f75e592..d13c93124651748eea2f75a9c45dce17c0f6bee8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -189,3 +189,6 @@ [submodule "dependencies/parsers/eelsdb"] path = dependencies/parsers/eelsdb url = https://gitlab.mpcdf.mpg.de/nomad-lab/eelsdb.git +[submodule "dependencies/parsers/example"] + path = dependencies/parsers/example + url = https://github.com/nomad-coe/nomad-parser-example.git diff --git a/Dockerfile b/Dockerfile index 24cd4c9da86acff1e87d1b94dee700e7d5601bea..ee9b542f126b369acde81bff026723af5aea21d9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,7 +47,7 @@ RUN pip install pandas RUN pip install h5py RUN pip install hjson RUN pip install scipy -RUN pip install scikit-learn==0.20.2 +RUN pip install scikit-learn RUN pip install ase==3.19.0 RUN pip install Pint RUN pip install matid @@ -69,8 +69,6 @@ WORKDIR /install COPY . /install RUN python setup.py compile RUN pip install .[all] -RUN python setup.py sdist -RUN cp dist/nomad-lab-*.tar.gz dist/nomad-lab.tar.gz RUN python -m nomad.cli dev metainfo > gui/src/metainfo.json RUN python -m nomad.cli dev search-quantities > gui/src/searchQuantities.json RUN python -m nomad.cli dev toolkit-metadata > gui/src/toolkitMetadata.json @@ -98,13 +96,17 @@ COPY --from=build /install/gui/src/toolkitMetadata.json /app/src/toolkitMetadata COPY --from=build /install/gui/src/units.js /app/src/units.js RUN yarn run build -# Build the Encyclopedia GUI in the gui build image +# Copy all sources and assets to the GUI build image, build it there, and then +# slim down the contents before they are copied to the final image RUN mkdir -p /encyclopedia WORKDIR /encyclopedia -COPY dependencies/encyclopedia-gui/client/src /encyclopedia/src -COPY dependencies/encyclopedia-gui/client/webpack.config.js /encyclopedia/webpack.config.js +COPY dependencies/encyclopedia-gui/client /encyclopedia/ RUN npm install webpack webpack-cli RUN npx webpack --mode=production +RUN rm -rf /encyclopedia/node_modules +RUN rm -rf /encyclopedia/src +RUN rm -f /encyclopedia/webpack.config.js +RUN rm -f /encyclopedia/.babelrc # Third, create a slim final image FROM final @@ -115,24 +117,22 @@ COPY . /app WORKDIR /app # transfer installed packages from dependency stage COPY --from=build /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.7/site-packages -RUN echo "copy 1" # copy the documentation, its files will be served by the API COPY --from=build /install/docs/.build /app/docs/.build -RUN echo "copy 2" -# copy the source distribution, its files will be served by the API -COPY --from=build /install/dist /app/dist -RUN echo "copy 3" # copy the nomad command COPY --from=build /usr/local/bin/nomad /usr/bin/nomad -RUN echo "copy 4" # copy the gui RUN mkdir -p /app/gui -COPY --from=gui_build /app/build /app/gui/build -RUN echo "copy 5" +COPY --from=gui_build /app/build /app/nomad/app/static/gui # copy the encyclopedia gui production code -COPY --from=gui_build /encyclopedia /app/dependencies/encyclopedia-gui/client -RUN rm -rf /app/dependencies/encyclopedia-gui/client/src -RUN echo "copy 6" +COPY --from=gui_build /encyclopedia /app/nomad/app/static/encyclopedia +# remove the developer config on the gui, will be generated by run.sh from nomad.yaml +RUN rm -f /app/nomad/app/static/gui/env.js +RUN rm -f /app/nomad/app/static/encyclopedia/conf.js +# build the python package dist +RUN python setup.py compile +RUN python setup.py sdist +RUN cp dist/nomad-lab-*.tar.gz dist/nomad-lab.tar.gz RUN mkdir -p /app/.volumes/fs RUN useradd -ms /bin/bash nomad diff --git a/MANIFEST.in b/MANIFEST.in index 55b766a293aea9c6617e81386601fab65a69e167..9492e8274f403b071e5ba50f445104ad90008f8d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,3 +6,4 @@ include LICENSE.txt include requirements.txt include auto_complete_install.sh include setup.json +recursive-include nomad/app/static *.css *.ico *.html *.json *.js *.map *.txt *.svg *.png \ No newline at end of file diff --git a/README.md b/README.md index f1377f62c55dc704412e828f5a2f0a3b90e4326a..d3ef99921569ba772156d3971410c208a607f815 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,9 @@ contributing, and API reference. Omitted versions are plain bugfix releases with only minor changes and fixes. +### v0.9.8 +- A new library for parsing text-based raw files. + ### v0.9.3 - Encyclopedia with dedicated materials search index. diff --git a/dependencies/parsers/crystal b/dependencies/parsers/crystal index abe6657cfda6cbc881a0ab8cf5edcc00c2eb8361..447cb20b5c8fb095bac5861721b8de96502b5058 160000 --- a/dependencies/parsers/crystal +++ b/dependencies/parsers/crystal @@ -1 +1 @@ -Subproject commit abe6657cfda6cbc881a0ab8cf5edcc00c2eb8361 +Subproject commit 447cb20b5c8fb095bac5861721b8de96502b5058 diff --git a/dependencies/parsers/elastic b/dependencies/parsers/elastic index c17dbecac0f395b48fc65b0c7dcc2ba4de1be271..9d4518fefb1f1146b7fa7ed95547822683020533 160000 --- a/dependencies/parsers/elastic +++ b/dependencies/parsers/elastic @@ -1 +1 @@ -Subproject commit c17dbecac0f395b48fc65b0c7dcc2ba4de1be271 +Subproject commit 9d4518fefb1f1146b7fa7ed95547822683020533 diff --git a/dependencies/parsers/example b/dependencies/parsers/example new file mode 160000 index 0000000000000000000000000000000000000000..c378ce3c667fa0b6bd93ecdfd5699b7b9e165fa5 --- /dev/null +++ b/dependencies/parsers/example @@ -0,0 +1 @@ +Subproject commit c378ce3c667fa0b6bd93ecdfd5699b7b9e165fa5 diff --git a/dependencies/parsers/gromacs b/dependencies/parsers/gromacs index 3f78e35b56714fe8c79b010ed52d97def19cb2dc..3b5866bc8dff77d398eddc6baceb19e1c30180c1 160000 --- a/dependencies/parsers/gromacs +++ b/dependencies/parsers/gromacs @@ -1 +1 @@ -Subproject commit 3f78e35b56714fe8c79b010ed52d97def19cb2dc +Subproject commit 3b5866bc8dff77d398eddc6baceb19e1c30180c1 diff --git a/dependencies/parsers/lammps b/dependencies/parsers/lammps index 7ed44cab4410099208f5e399bfa4c1dc2e9c29fe..8944d5ffd4cac01e43aaac5c5687b0a8831f2bc7 160000 --- a/dependencies/parsers/lammps +++ b/dependencies/parsers/lammps @@ -1 +1 @@ -Subproject commit 7ed44cab4410099208f5e399bfa4c1dc2e9c29fe +Subproject commit 8944d5ffd4cac01e43aaac5c5687b0a8831f2bc7 diff --git a/dependencies/parsers/vasp b/dependencies/parsers/vasp index 10973cb74a154c5896633cb50f6e576fddd72852..56eb84fffa3ae25a4b8dc10aa56da85a4fe6584d 160000 --- a/dependencies/parsers/vasp +++ b/dependencies/parsers/vasp @@ -1 +1 @@ -Subproject commit 10973cb74a154c5896633cb50f6e576fddd72852 +Subproject commit 56eb84fffa3ae25a4b8dc10aa56da85a4fe6584d diff --git a/dependencies/parsers/wien2k b/dependencies/parsers/wien2k index cf6abfe712ff2d0052947f46bdb27131ac6fbaf8..0bfb17daec156d26110d55cd0918d8fb584f7fac 160000 --- a/dependencies/parsers/wien2k +++ b/dependencies/parsers/wien2k @@ -1 +1 @@ -Subproject commit cf6abfe712ff2d0052947f46bdb27131ac6fbaf8 +Subproject commit 0bfb17daec156d26110d55cd0918d8fb584f7fac diff --git a/dependencies/python_common b/dependencies/python_common index afdd0937aab2681ca3912cfd9d95c7633fdcd7b9..c1aca04237d69097bbeb17d3a397be66e9c6797f 160000 --- a/dependencies/python_common +++ b/dependencies/python_common @@ -1 +1 @@ -Subproject commit afdd0937aab2681ca3912cfd9d95c7633fdcd7b9 +Subproject commit c1aca04237d69097bbeb17d3a397be66e9c6797f diff --git a/docs/api_tutorial.md b/docs/api.md similarity index 99% rename from docs/api_tutorial.md rename to docs/api.md index 0a8371b478ea4d5adc6ff37cbedf83a0ccadd2ef..5e3297b5b7ccc8816684474ed3d0f1410645aefe 100644 --- a/docs/api_tutorial.md +++ b/docs/api.md @@ -1,4 +1,4 @@ -# API Tutorials +# How to use the APIs The NOMAD Repository and Archive offers all its functionality through an application programming interface (API). More specifically a [RESTful HTTP API](https://en.wikipedia.org/wiki/Representational_state_transfer) that allows you @@ -38,7 +38,7 @@ Let's say you want to see the repository metadata (i.e. the information that you our gui) for entries that fit search criteria, like compounds having atoms *Si* and *O* in it: -``` +```sh curl -X GET "http://nomad-lab.eu/prod/rae/api/repo/?atoms=Si&atoms=O" ``` @@ -46,7 +46,7 @@ Here we used curl to send an HTTP GET request to return the resource located by In practice you can omit the `-X GET` (which is the default) and you might want to format the output: -``` +```sh curl "http://nomad-lab.eu/prod/rae/api/repo/?atoms=Si&atoms=O" | python -m json.tool ``` @@ -68,21 +68,21 @@ Similar functionality is offered to download archive or raw data. Let's say you identified an entry (given via a `upload_id`/`calc_id`, see the query output), and you want to download it: -``` +```sh curl "http://nomad-lab.eu/prod/rae/api/raw/calc/JvdvikbhQp673R4ucwQgiA/k-ckeQ73sflE6GDA80L132VCWp1z/*" -o download.zip ``` With `*` you basically requests all the files under an entry or path.. If you need a specific file (that you already know) of that calculation: -``` +```sh curl "http://nomad-lab.eu/prod/rae/api/raw/calc/JvdvikbhQp673R4ucwQgiA/k-ckeQ73sflE6GDA80L132VCWp1z/INFO.OUT" ``` You can also download a specific file from the upload (given a `upload_id`), if you know the path of that file: -``` +```sh curl "http://nomad-lab.eu/prod/rae/api/raw/JvdvikbhQp673R4ucwQgiA/exciting_basis_set_error_study/monomers_expanded_k8_rgkmax_080_PBE/72_Hf/INFO.OUT" ``` @@ -90,27 +90,27 @@ If you have a query that is more selective, you can also download all results. Here all compounds that only consist of Si, O, bulk material simulations of cubic systems (currently ~100 entries): -``` +```sh curl "http://nomad-lab.eu/prod/rae/api/raw/query?only_atoms=Si&only_atoms=O&system=bulk&crystal_system=cubic" -o download.zip ``` Here are a few more examples for downloading the raw data of based on DOI or dataset. You will have to encode non URL safe characters in potential dataset names (e.g. with a service like [www.urlencoder.org](https://www.urlencoder.org/)): -``` +```sh curl "http://nomad-lab.eu/prod/rae/api/raw/query?datasets.doi=10.17172/NOMAD/2020.03.18-1" -o download.zip curl "http://nomad-lab.eu/prod/rae/api/raw/query?dataset=Full%20ahnarmonic%20stAViC%20approach%3A%20Silicon%20and%20SrTiO3" -o download.zip ``` In a similar way you can see the archive of an entry: -``` +```sh curl "http://nomad-lab.eu/prod/rae/api/archive/f0KQE2aiSz2KRE47QtoZtw/6xe9fZ9xoxBYZOq5lTt8JMgPa3gX" | python -m json.tool ``` Or query and display the first page of 10 archives: -``` +```sh curl "http://nomad-lab.eu/prod/rae/api/archive/query?only_atoms=Si&only_atoms=O" | python -m json.tool ``` @@ -164,7 +164,7 @@ Optionally, if you need to access your private data, the package *python-keycloa required to conveniently acquire the necessary tokens to authenticate your self towards NOMAD. -``` +```sh pip install bravado pip install python-keycloak ``` @@ -386,20 +386,20 @@ The shell tool *curl* can be used to call most API endpoints. Most endpoints for or downloading data are only **GET** operations controlled by URL parameters. For example: Downloading data: -``` +```sh curl http://nomad-lab.eu/prod/rae/api/raw/query?upload_id= -o download.zip ``` It is a litle bit trickier, if you need to authenticate yourself, e.g. to download not yet published or embargoed data. All endpoints support and most require the use of an access token. To acquire an access token from our usermanagement system with curl: -``` +```sh curl --data 'grant_type=password&client_id=nomad_public&username=&password=' \ https://nomad-lab.eu/fairdi/keycloak/auth/realms/fairdi_nomad_prod/protocol/openid-connect/token ``` You can use the access-token with: -``` +```sh curl -H 'Authorization: Bearer ' \ http://nomad-lab.eu/prod/rae/api/raw/query?upload_id= -o download.zip ``` diff --git a/docs/api.rst b/docs/api_reference.rst similarity index 100% rename from docs/api.rst rename to docs/api_reference.rst diff --git a/docs/archive.rst b/docs/archive.rst index 59c4e7f0b16825cbf110a2dbbef84200afdcc26e..2e70bda34593f4dab2e4010a07762e83b2842956 100644 --- a/docs/archive.rst +++ b/docs/archive.rst @@ -1,7 +1,7 @@ .. _access-the-archive-label: -Using the NOMAD Archive -======================= +Data Access (Archive) +===================== Of course, you can access the NOMAD Archive directly via the NOMAD API (see the `API tutorial `_ and `API reference `_). But, it is more effective and convenient to use NOMAD's Python client diff --git a/docs/client/cli_use_cases.rst b/docs/client/cli_use_cases.rst index 871d74c8886e039647e94103340e600347f8e930..fb7ca41283a52f8b6ed09ed73aad3d64d75eabb8 100644 --- a/docs/client/cli_use_cases.rst +++ b/docs/client/cli_use_cases.rst @@ -11,7 +11,7 @@ are up and running and both have access to the underlying file storage, part of which is mounted inside each container under :code:`.volumes/fs`. With both the source and target deployment running, you can use the -:code::ref:`cli_ref:mirror` command to transfer the data from source to target. The +:ref:`cli_ref:mirror` command to transfer the data from source to target. The mirror will copy everything: i.e. the raw data, archive data and associated metadata in the database. diff --git a/docs/client/client.rst b/docs/client/client.rst index 26d689f0a290815984f468ce674a6e1684ac4322..81be26bc5bfa307bfd9348dd3a88b78da8a8cde4 100644 --- a/docs/client/client.rst +++ b/docs/client/client.rst @@ -1,5 +1,5 @@ -NOMAD Python package and CLI ------------------------------------------------------ +NOMAD's Python library +---------------------- The :code:`nomad` python package comes with a command line interface (CLI) that can be accessed after installation by simply running the :code:`nomad` command in your terminal. The CLI provides a hiearchy of commands by using the `click diff --git a/docs/client/install.rst b/docs/client/install.rst index 940fa1bc789fe602dcf9562cbd50793758706698..1414148eb451fbf13e1e95807dd3633edbf4c4f5 100644 --- a/docs/client/install.rst +++ b/docs/client/install.rst @@ -1,3 +1,5 @@ +.. _install-client: + Install the NOMAD client library ================================ diff --git a/docs/dev/dev_guidelines.rst b/docs/dev/dev_guidelines.rst deleted file mode 100644 index a57e96864c51f07e81c37e534742d416cd565eef..0000000000000000000000000000000000000000 --- a/docs/dev/dev_guidelines.rst +++ /dev/null @@ -1,331 +0,0 @@ -Development guidelines -====================== - -Design principles ------------------ - -- simple first, complicated only when necessary -- adopting generic established 3rd party solutions before implementing specific solutions -- only uni directional dependencies between components/modules, no circles -- only one language: Python (except, GUI of course) - - -Source code & Git repository ----------------------------- - -Code Rules -^^^^^^^^^^ - -The are some *rules* or better strong *guidelines* for writing code. The following -applies to all python code (and were applicable, also to JS and other code): - -- Use an IDE (e.g. `vscode `_ or otherwise automatically - enforce code (`formatting and linting `_). - Use ``nomad qa`` before committing. This will run all tests, static type checks, linting, etc. - -- There is a style guide to python. Write `pep-8 `_ - compliant python code. An exception is the line cap at 79, which can be broken but keep it 90-ish. - -- Test the public API of each sub-module (i.e. python file) - -- Be `pythonic `_ and watch - `this `_. - -- Document any *public* API of each sub-module (e.g. python file). Public meaning API that - is exposed to other sub-modules (i.e. other python files). - -- Use google `docstrings `_. - -- Add your doc-strings to the sphinx documentation in ``docs``. Use .md, follow the example. - Markdown in sphix is supported via `recommonmark - `_ - and `AutoStructify `_ - -- The project structure is according to `this guid `_. - Keep it! - - -CI/CD -^^^^^ - -These *guidelines* are partially enforced by CI/CD. As part of CI all tests are run on all -branches; further we run a *linter*, *pep8* checker, and *mypy* (static type checker). You can -run ``nomad qa`` to run all these tests and checks before committing. - -The CI/CD will run on all refs that do not start with ``dev-``. The CI/CD will -not release or deploy anything automatically, but it can be manually triggered after the -build and test stage completed successfully. - - -Git/GitLab -^^^^^^^^^^ - -The ``master`` branch of our repository is *protected*. You must not (even if you have -the rights) commit to it directly. The ``master`` branch references the latest official -release (i.e. what the current NOMAD runs on). The current development is represented by -*version* branches, named ``vx.x.x``. Usually there are two or more of these branched, -representing the development on *minor/bugfix* versions and the next *major* version(s). -Ideally these *version* branches are also not manually push to. - -Instead you develop -on *feature* branches. These are branches that are dedicated to implement a single feature. -They are short lived and only exist to implement a single feature. - -The lifecycle of a *feature* branch should look like this: - -- create the *feature* branch from the last commit on the respective *version* branch that passes CI - -- do your work and push until you are satisfied and the CI passes - -- create a merge request on GitLab - -- discuss the merge request on GitLab - -- continue to work (with the open merge request) until all issues from the discussion are resolved - -- the maintainer performs the merge and the *feature* branch gets deleted - -While working on a feature, there are certain practices that will help us to create -a clean history with coherent commits, where each commit stands on its own. - -.. code-block:: sh - - git commit --amend - -If you committed something to your own feature branch and then realize by CI that you have -some tiny error in it that you need to fix, try to amend this fix to the last commit. -This will avoid unnecessary tiny commits and foster more coherent single commits. With `amend` -you are basically adding changes to the last commit, i.e. editing the last commit. If -you push, you need to force it ``git push origin feature-branch -f``. So be careful, and -only use this on your own branches. - -.. code-block:: sh - - git rebase - -Lets assume you work on a bigger feature that takes more time. You might want to merge -the version branch into your feature branch from time to time to get the recent changes. -In these cases, use rebase and not merge. Rebase puts your branch commits in front of the -merged commits instead of creating a new commit with two ancestors. It basically moves the -point where you initially branched away from the version branch to the current position in -the version branch. This will avoid merges, merge commits, and generally leave us with a -more consistent history. You can also rebase before create a merge request, basically -allowing for no-op merges. Ideally the only real merges that we ever have, are between -version branches. - -.. code-block:: sh - - git merge --squash - -When you need multiple branches to implement a feature and merge between them, try to -use `squash`. Squashing basically puts all commits of the merged branch into a single commit. -It basically allows you to have many commits and then squash them into one. This is useful -if these commits where just made for synchronization between workstations or due to -unexpected errors in CI/CD, you needed a save point, etc. Again the goal is to have -coherent commits, where each commits makes sense on its own. - -Often a feature is also represented by an *issue* on GitLab. Please mention the respective -issues in your commits by adding the issue id at the end of the commit message: `My message. #123`. - -We tag releases with ``vX.X.X`` according to the regular semantic versioning practices. -After releasing and tagging the *version* branch is removed. Do not confuse tags with *version* branches. -Remember that tags and branches are both Git references and you can accidentally pull/push/checkout a tag. - -The main NOMAD GitLab-project (``nomad-fair``) uses Git-submodules to maintain its -parsers and other dependencies. All these submodules are places in the `/dependencies` -directory. There are helper scripts to install (`dependencies.sh`, see :ref:`setup `) and -commit changes to all submodules (`dependencies-git.sh`). After merging or checking out, -you have to make sure that the modules are updated to not accidentally commit old -submodule commits again. Usually you do the following to check if you really have a -clean working directory. - -.. code-block:: sh - - git checkout something-with-changes - git submodule update - git status - - -Terms and Identifiers ---------------------- - -There are is some terminology consistently used in this documentation and the source -code. Use this terminology for identifiers. - -Do not use abbreviations. There are (few) exceptions: ``proc`` (processing); ``exc``, ``e`` (exception); -``calc`` (calculation), ``repo`` (repository), ``utils`` (utilities), and ``aux`` (auxiliary). -Other exceptions are ``f`` for file-like streams and ``i`` for index running variables. -Btw., the latter is almost never necessary in python. - -Terms: - -- upload: A logical unit that comprises one (.zip) file uploaded by a user. -- calculation: A computation in the sense that is was created by an individual run of a CMS code. -- raw file: User uploaded files (e.g. part of the uploaded .zip), usually code input or output. -- upload file/uploaded file: The actual (.zip) file a user uploaded -- mainfile: The mainfile output file of a CMS code run. -- aux file: Additional files the user uploaded within an upload. -- repo entry: Some quantities of a calculation that are used to represent that calculation in the repository. -- archive data: The normalized data of one calculation in nomad's meta-info-based format. - - -.. _id-reference-label: - -Ids ---- - -Throughout nomad, we use different ids. If something -is called *id*, it is usually a random uuid and has no semantic connection to the entity -it identifies. If something is called a *hash* than it is a hash build based on the -entity it identifies. This means either the whole thing or just some properties of -said entities. - -- The most common hashes is the ``calc_hash`` based on mainfile and auxfile contents. -- The ``upload_id`` is a UUID assigned at upload time and never changed afterwards. -- The ``mainfile`` is a path within an upload that points to a main code output file. - Since, the upload directory structure does not change, this uniquely ids a calc within the upload. -- The ``calc_id`` (internal calculation id) is a hash over the ``mainfile`` and respective - ``upload_id``. Therefore, each `calc_id` ids a calc on its own. -- We often use pairs of `upload_id/calc_id`, which in many context allow to resolve a calc - related file on the filesystem without having to ask a database about it. -- The ``pid`` or (``coe_calc_id``) is an sequential interger id. -- Calculation ``handle`` or ``handle_id`` are created based on those ``pid``. - To create hashes we use :py:func:`nomad.utils.hash`. - - -NOMAD-coe Dependencies ----------------------- - -We currently use git submodules to maintain references to NOMAD-coe dependencies. -All dependencies are python packages and installed via pip to your python environement. - -This allows us to target (e.g. install) individual commits. More importantly, we can address c -ommit hashes to identify exact parser/normalizer versions. On the downside, common functions -for all dependencies (e.g. the python-common package, or nomad_meta_info) cannot be part -of the nomad-FAIRDI project. In general, it is hard to simultaneously develop nomad-FAIRDI -and NOMAD-coe dependencies. - -Another approach is to integrate the NOMAD-coe sources with nomad-FAIRDI. The lacking -availability of individual commit hashes, could be replaces with hashes of source-code -files. - -We use the branch ``nomad-fair`` on all dependencies for nomad-FAIRDI specific changes. - - -Parsers -^^^^^^^ - -There are several steps to take, to wrap a NOMAD-coe parser into a nomad@FAIRDI parser: - -- Implement ``nomadcore.baseclasses.ParserInterface`` or a class with a similar constructutor - and `parse` method interface. -- Make sure that the meta-info is - only loaded for each parse instance, not for each parser run. -- Have a root package that bears the parser name, e.g. ``vaspparser`` -- The important classes (e.g. the parser interface implementation) in the root module - (e.g. ``vaspparser/__init__.py``) -- Only use sub-modules were necessary. Try to avoid sub-directories -- Have a test module. Don't go overboard with the test data. -- Make it a pypi-style package, i.e. create ``setup.py`` script. -- The package name should be the parser name, e.g. ``vaspparser``. -- Let the parser logging as it is. We will catch it with a handler installed on the root logger. - This handler will redirect all legacy log events and put it though the nomad@FAIRDI - treatment described below. -- Remove all scala code. - - -Normalizers -^^^^^^^^^^^ - -We are rewriting all NOMAD-coe normalizers, see :py:mod:`nomad.normalizing`. - - -Logging -------- - -There are three important prerequisites to understand about nomad-FAIRDI's logging: - -- All log entries are recorded in a central elastic search database. To make this database - useful, log entries must be sensible in size, frequence, meaning, level, and logger name. - Therefore, we need to follow some rules when it comes to logging. -- We use an *structured* logging approach. Instead of encoding all kinds of information - in log messages, we use key-value pairs that provide context to a log *event*. In the - end all entries are stored as JSON dictionaries with ``@timestamp``, ``level``, - ``logger_name``, ``event`` plus custom context data. Keep events very short, most - information goes into the context. -- We use logging to inform about the state of nomad-FAIRDI, not about user - behavior, input, data. Do not confuse this when determining the log-level for an event. - For example, a user providing an invalid upload file, for example, should never be an error. - -Please follow the following rules when logging: - -- If a logger is not already provided, only use - :py:func:`nomad.utils.get_logger` to acquire a new logger. Never use the - build-in logging directly. These logger work like the system loggers, but - allow you to pass keyword arguments with additional context data. See also - the `structlog docs `_. -- In many context, a logger is already provided (e.g. api, processing, parser, normalizer). - This provided logger has already context information bounded. So it is important to - use those instead of acquiring your own loggers. Have a look for methods called - ``get_logger`` or attributes called ``logger``. -- Keep events (what usually is called *message*) very short. Examples are: *file uploaded*, - *extraction failed*, etc. -- Structure the keys for context information. When you analyse logs in ELK, you will - see that the set of all keys over all log entries can be quit large. Structure your - keys to make navigation easier. Use keys like ``nomad.proc.parser_version`` instead of - ``parser_version``. Use module names as prefixes. -- Don't log everything. Try to anticipate, how you would use the logs in case of bugs, - error scenarios, etc. -- Don't log sensitive data. -- Think before logging data (especially dicts, list, numpy arrays, etc.). -- Logs should not be abused as a *printf*-style debugging tool. - -Used log keys -^^^^^^^^^^^^^ -The following keys are used in the final logs that are piped to Logstash. -Notice that the key name is automatically formed by a separate formatter and -may differ from the one used in the actual log call. - -Keys that are autogenerated for all logs: - - - ``@timestamp``: Timestamp for the log - - ``@version``: Version of the logger - - ``host``: The host name from which the log originated - - ``path``: Path of the module from which the log was created - - ``tags``: Tags for this log - - ``type``: The `message_type` as set in the LogstashFormatter - - ``level``: The log level: ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR`` - - ``logger_name``: Name of the logger - - ``nomad.service``: The service name as configured in ``config.py`` - - ``nomad.release``: The release name as configured in ``config.py`` - -Keys that are present for events related to processing an entry: - - - ``nomad.upload_id``: The id of the currently processed upload - - ``nomad.calc_id``: The id of the currently processed entry - - ``nomad.mainfile``: The mainfile of the currently processed entry - -Keys that are present for events related to exceptions: - - - ``exc_info``: Stores the full python exception that was encountered. All - uncaught exceptions will be stored automatically here. - - ``digest``: If an exception was raised, the last 256 characters of the message - are stored automatically into this key. If you wish to search for exceptions - in Kibana, you will want to use this value as it will be indexed unlike the - full exception object. - - -Copyright Notices ------------------ - -We follow this `recommendation `_ -of the Linux Foundation for the copyright notice that is placed on top of each source -code file. - -It is intended to provide a broad generic statement that allows all authors/contributors -of the NOMAD project to claim their copyright, independent of their organization or -individual ownership. - -You can simply copy the notice from another file. From time to time we can use a tool -like `licenseheaders `_ to ensure correct -notices. In addition we keep an purely informative AUTHORS file. \ No newline at end of file diff --git a/docs/dev/setup.md b/docs/dev/setup.md deleted file mode 100644 index 0b5089a151c211756068c00ca67798c308edace8..0000000000000000000000000000000000000000 --- a/docs/dev/setup.md +++ /dev/null @@ -1,397 +0,0 @@ -# Development Setup - -## Introduction -The nomad infrastructure consists of a series of nomad and 3rd party services: -- nomad worker (python): task worker that will do the processing -- nomad app (python): the nomad app and it's REST APIs -- nomad gui: a small server serving the web-based react gui -- proxy: an nginx server that reverse proxyies all services under one port -- elastic search: nomad's search and analytics engine -- mongodb: used to store processing state -- rabbitmq: a task queue used to distribute work in a cluster - -All 3rd party services should be run via *docker-compose* (see blow). The -nomad python services can be run with python to develop them. -The gui can be run with a development server via yarn. - -Below you will find information on how to install all python dependencies and code -manually. How to use *docker*/*docker-compose*. How run 3rd-party services with *docker-compose*. - -Keep in mind the *docker-compose* configures all services in a way that mirror -the configuration of the python code in `nomad/config.py` and the gui config in -`gui/.env.development`. - -To learn about how to run everything in docker, e.g. to operate a NOMAD OASIS in -production, go (here)(/app/docs/ops.html). - -## Install python code and dependencies - -### Cloning and development tools -If not already done, you should clone nomad and create a python virtual environment. - -To clone the repository: -``` -git clone git@gitlab.mpcdf.mpg.de:nomad-lab/nomad-FAIR.git -cd nomad-FAIR -``` - -### C libs - -Even though the NOMAD infrastructure is written in python, there is a C library -required by one of our python dependencies. - -#### libmagic - -Libmagic allows to determine the MIME type of files. It should be installed on most -unix/linux systems. It can be installed on MacOS with homebrew: - -``` -brew install libmagic -``` - -### Virtual environment - -#### pyenv -The nomad code currently targets python 3.7. If you host machine has an older version installed, -you can use [pyenv](https://github.com/pyenv/pyenv) to use python 3.7 in parallel to your -system's python. - -#### virtualenv -We strongly recommend to use *virtualenv* to create a virtual environment. It will allow you -to keep nomad and its dependencies separate from your system's python installation. -Make sure to base the virtual environment on Python 3. -To install *virtualenv*, create an environment and activate the environment use: -``` -pip install virtualenv -virtualenv -p `which python3` .pyenv -source .pyenv/bin/activate -``` - -#### Conda -If you are a conda user, there is an equivalent, but you have to install pip and the -right python version while creating the environment. -``` -conda create --name nomad_env pip python=3.7 -conda activate nomad_env -``` - -To install libmagick for conda, you can use (other channels might also work): -``` -conda install -c conda-forge --name nomad_env libmagic -``` - -#### pip -Make sure you have the most recent version of pip: -``` -pip install --upgrade pip -``` - - -The next steps can be done using the `setup.sh` script. If you prefer to understand all -the steps and run them manually, read on: - - -### Install NOMAD-coe dependencies. -Nomad is based on python modules from the NOMAD-coe project. -This includes parsers, python-common and the meta-info. These modules are maintained as -their own GITLab/git repositories. To clone and initialize them run: - -``` -git submodule update --init -``` - -All requirements for these submodules need to be installed and they need to be installed -themselves as python modules. Run the `dependencies.sh` script that will install -everything into your virtual environment: -``` -./dependencies.sh -e -``` - -The `-e` option will install the NOMAD-coe dependencies with symbolic links allowing you -to change the downloaded dependency code without having to reinstall after. - -### Install nomad -Finally, you can add nomad to the environment itself (including all extras) -``` -pip install -e .[all] -``` - -If pip tries to use and compile sources and this creates errors, it can be told to prefer binary version: - -``` -pip install -e .[all] --prefer-binary -``` - -### Generate GUI artifacts -The NOMAD GUI requires static artifacts that are generated from the NOMAD Python codes. -``` -nomad dev metainfo > gui/src/metainfo.json -nomad dev searchQuantities > gui/src/searchQuantities.json -nomad dev units > gui/src/units.js -./gitinfo.sh -``` - -In additional, you have to do some more steps to prepare your working copy to run all -the tests. See below. - -## Build and run the infrastructure with docker - -### Docker and nomad -Nomad depends on a set of databases, search engines, and other services. Those -must run to make use of nomad. We use *docker* and *docker-compose* to create a -unified environment that is easy to build and to run. - -You can use *docker* to run all necessary 3rd-party components and run all nomad -services manually from your python environment. You can also run nomad in docker, -but using Python is often preferred during development, since it allows -you change things, debug, and re-run things quickly. The later one brings you -closer to the environment that will be used to run nomad in production. For -development we recommend to skip the next step. - -### Docker images for nomad -Nomad comprises currently two services, -the *worker* (does the actual processing), and the *app*. Those services can be -run from one image that have the nomad python code and all dependencies installed. This -is covered by the `Dockerfile` in the root directory -of the nomad sources. The gui is served also served from the *app* which entails the react-js frontend code. - -Before building the image, make sure to execute -``` -./gitinfo.sh -``` -This allows the app to present some information about the current git revision without -having to copy the git itself to the docker build context. - -### Run necessary 3-rd party services with docker-compose - -You can run all containers with: -``` -cd ops/docker-compose/infrastructure -docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d mongo elastic rabbitmq -``` - -To shut down everything, just `ctrl-c` the running output. If you started everything -in *deamon* mode (`-d`) use: -``` -docker-compose down -``` - -Usually these services only used by the nomad containers, but sometimes you also -need to check something or do some manual steps. - -The *docker-compose* can be overriden with additional seetings. See documentation section on -operating NOMAD for more details. The override `docker-compose.override.yml` will -expose all database ports to the hostmachine and should be used in development. To use -it run docker-compose with `-f docker-compose.yml -f docker-compose.override.yml`. - -### ELK (elastic stack) - -If you run the ELK stack (and enable logstash in nomad/config.py), -you can reach the Kibana with [localhost:5601](http://localhost:5601). -The index prefix for logs is `logstash-`. The ELK is only available with the -`docker-compose.dev-elk.yml` override. - -### mongodb and elastic search - -You can access mongodb and elastic search via your preferred tools. Just make sure -to use the right ports (see above). - -## Run nomad services - -### API and worker - -To simply run a worker with the installed nomad cli, do (from the root) -``` -nomad admin run worker -``` - -To run it directly with celery, do (from the root) -``` -celery -A nomad.processing worker -l info -``` - -You can also run worker and app together: -``` -nomad admin run appworker -``` - -### GUI -When you run the gui on its own (e.g. with react dev server below), you have to have -the API running manually also. This *inside docker* API is configured for ngingx paths -and proxies, which are run by the gui container. But you can run the *production* gui -in docker and the dev server gui in parallel with an API in docker. -Either with docker, or: -``` -cd gui -yarn -yarn start -``` - -## Run the tests - -### additional settings and artifacts -To run the tests some additional settings and files are necessary that are not part -of the code base. - -First you need to create a `nomad.yaml` with the admin password for the user management -system: -``` -keycloak: - password: -``` - -Secondly, you need to provide the `springer.msg` Springer materials database. It can -be copied from `/nomad/fairdi/db/data/springer.msg` on our servers and should -be placed at `nomad/normalizing/data/springer.msg`. - -Thirdly, you have to provide static files to serve the docs and NOMAD distribution: -``` -cd docs -make html -cd .. -python setup.py compile -python setup.py sdist -cp dist/nomad-lab-*.tar.gz dist/nomad-lab.tar.gz -``` - -### run the necessary infrastructure -You need to have the infrastructure partially running: elastic, rabbitmq. -The rest should be mocked or provided by the tests. Make sure that you do no run any -worker, as they will fight for tasks in the queue. -``` -cd ops/docker-compose -docker-compose up -d elastic rabbitmq -cd ../.. -pytest -svx tests -``` - -We use pylint, pycodestyle, and mypy to ensure code quality. To run those: -``` -nomad dev qa --skip-test -``` - -To run all tests and code qa: -``` -nomad dev qa -``` - -This mimiques the tests and checks that the GitLab CI/CD will perform. - - -## Setup your (I)DE - -The documentation section on development guidelines details how the code is organized, -tested, formatted, and documented. To help you meet these guidelines, we recomment to -use a proper IDE for development and ditch any VIM/Emacs (mal-)practices. - -### Visual Studio Code - -Here are some VSCode settings that will enable features for linting, some auto formating, -line size ruler, etc. -```json -{ - "python.venvPath": "${workspaceFolder}/.pyenv", - "python.pythonPath": "${workspaceFolder}/.pyenv/bin/python", - "git.ignoreLimitWarning": true, - "editor.rulers": [90], - "editor.renderWhitespace": "all", - "editor.tabSize": 4, - "[javascript]": { - "editor.tabSize": 2 - }, - "files.trimTrailingWhitespace": true, - "git.enableSmartCommit": true, - "eslint.autoFixOnSave": true, - "python.linting.pylintArgs": [ - "--load-plugins=pylint_mongoengine,nomad/metainfo/pylint_plugin", - ], - "python.linting.pep8Path": "pycodestyle", - "python.linting.pep8Enabled": true, - "python.linting.pep8Args": ["--ignore=E501,E701"], - "python.linting.mypyEnabled": true, - "python.linting.mypyArgs": [ - "--ignore-missing-imports", - "--follow-imports=silent", - "--no-strict-optional" - ], - "workbench.colorCustomizations": { - "editorError.foreground": "#FF2222", - "editorOverviewRuler.errorForeground": "#FF2222", - "editorWarning.foreground": "#FF5500", - "editorOverviewRuler.warningForeground": "#FF5500", - "activityBar.background": "#4D2111", - "titleBar.activeBackground": "#6B2E18", - "titleBar.activeForeground": "#FDF9F7" - }, - "files.watcherExclude": { - "**/.git/objects/**": true, - "**/.git/subtree-cache/**": true, - "**/node_modules/*/**": true, - "**/.pyenv/*/**": true, - "**/__pycache__/*/**": true, - "**/.mypy_cache/*/**": true, - "**/.volumes/*/**": true, - "**/docs/.build/*/**": true - } -} -``` - -Here are some example launch configs for VSCode: - -```json -{ - "version": "0.2.0", - "configurations": [ - { - "type": "chrome", - "request": "launch", - "name": "Launch Chrome against localhost", - "url": "http://localhost:3000", - "webRoot": "${workspaceFolder}/gui" - }, - { - "name": "Python: API Flask (0.11.x or later)", - "type": "python", - "request": "launch", - "module": "flask", - "env": { - "FLASK_APP": "nomad/app/__init__.py" - }, - "args": [ - "run", - "--port", - "8000", - "--no-debugger", - "--no-reload" - ] - }, - { - "name": "Python: some test", - "type": "python", - "request": "launch", - "cwd": "${workspaceFolder}", - "program": "${workspaceFolder}/.pyenv/bin/pytest", - "args": [ - "-sv", - "tests/test_cli.py::TestClient::test_mirror" - ] - }, - { - "name": "Python: Current File", - "type": "python", - "request": "launch", - "program": "${file}" - }, - { - "name": "Python: Attach", - "type": "python", - "request": "attach", - "localRoot": "${workspaceFolder}", - "remoteRoot": "${workspaceFolder}", - "port": 3000, - "secret": "my_secret", - "host": "localhost" - } - ] -} -``` diff --git a/docs/developers.md b/docs/developers.md new file mode 100644 index 0000000000000000000000000000000000000000..a58497102ae4502c39aff141833d93becc17933f --- /dev/null +++ b/docs/developers.md @@ -0,0 +1,612 @@ +# Developing NOMAD + +## Getting started + +### Clone the sources +If not already done, you should clone nomad. To clone the main NOMAD repository: +``` +git clone git@gitlab.mpcdf.mpg.de:nomad-lab/nomad-FAIR.git nomad +cd nomad +``` + +### Prepare your Python environment + +You work in a Python virtual environment. + +#### pyenv +The nomad code currently targets python 3.7. If you host machine has an older version installed, +you can use [pyenv](https://github.com/pyenv/pyenv) to use python 3.7 in parallel to your +system's python. + +#### virtualenv +We strongly recommend to use *virtualenv* to create a virtual environment. It will allow you +to keep nomad and its dependencies separate from your system's python installation. +Make sure to base the virtual environment on Python 3. +To install *virtualenv*, create an environment and activate the environment use: +``` +pip install virtualenv +virtualenv -p `which python3` .pyenv +source .pyenv/bin/activate +``` + +#### conda +If you are a conda user, there is an equivalent, but you have to install pip and the +right python version while creating the environment. +```sh +conda create --name nomad_env pip python=3.7 +conda activate nomad_env +``` + +To install libmagick for conda, you can use (other channels might also work): +```sh +conda install -c conda-forge --name nomad_env libmagic +``` + +#### pip +Make sure you have the most recent version of pip: +```sh +pip install --upgrade pip +``` + + +#### Missing system libraries (e.g. on MacOS) + +Even though the NOMAD infrastructure is written in python, there is a C library +required by one of our python dependencies. Libmagic is missing on some systems. +Libmagic allows to determine the MIME type of files. It should be installed on most +unix/linux systems. It can be installed on MacOS with homebrew: + +```sh +brew install libmagic +``` + +### Install sub-modules. +Nomad is based on python modules from the NOMAD-coe project. +This includes parsers, python-common and the meta-info. These modules are maintained as +their own GITLab/git repositories. To clone and initialize them run: + +```sh +git submodule update --init +``` + +All requirements for these submodules need to be installed and they need to be installed +themselves as python modules. Run the `dependencies.sh` script that will install +everything into your virtual environment: +```sh +./dependencies.sh -e +``` + +The `-e` option will install the NOMAD-coe dependencies with symbolic links allowing you +to change the downloaded dependency code without having to reinstall after. + +### Install nomad +Finally, you can add nomad to the environment itself (including all extras) +```sh +pip install -e .[all] +``` + +If pip tries to use and compile sources and this creates errors, it can be told to prefer binary version: + +```sh +pip install -e .[all] --prefer-binary +``` + +### Generate GUI artifacts +The NOMAD GUI requires static artifacts that are generated from the NOMAD Python codes. +```sh +nomad dev metainfo > gui/src/metainfo.json +nomad dev search-quantities > gui/src/searchQuantities.json +nomad dev units > gui/src/units.js +./gitinfo.sh +``` + +In additional, you have to do some more steps to prepare your working copy to run all +the tests. See below. + +## Running the infrastructure + +To run NOMAD, some 3-rd party services are neeed +- elastic search: nomad's search and analytics engine +- mongodb: used to store processing state +- rabbitmq: a task queue used to distribute work in a cluster + +All 3rd party services should be run via *docker-compose* (see below). +Keep in mind the *docker-compose* configures all services in a way that mirror +the configuration of the python code in `nomad/config.py` and the gui config in +`gui/.env.development`. + +You can run all services with: +```sh +cd ops/docker-compose/infrastructure +docker-compose up -d mongo elastic rabbitmq +``` + +To shut down everything, just `ctrl-c` the running output. If you started everything +in *deamon* mode (`-d`) use: +```sh +docker-compose down +``` + +Usually these services only used by NOMAD, but sometimes you also +need to check something or do some manual steps. You can access mongodb and elastic search +via your preferred tools. Just make sure to use the right ports. + +## Running NOMAD + +NOMAD consist of the NOMAD app/api, a worker, and the GUI. You can run app and worker with +the NOMAD cli: + +```sh +nomad admin run app +nomad admin run worker +nomad admin run appworker +``` + +The app will run at port 8000 by default. + +To run the worker directly with celery, do (from the root) +```sh +celery -A nomad.processing worker -l info +``` + +When you run the gui on its own (e.g. with react dev server below), you have to have +the app manually also. +```sh +cd gui +yarn +yarn start +``` + +## Running tests + +To run the tests some additional settings and files are necessary that are not part +of the code base. + +First you need to create a `nomad.yaml` with the admin password for the user management +system: +```yaml +keycloak: + password: +``` + +Secondly, you need to provide the `springer.msg` Springer materials database. It can +be copied from `/nomad/fairdi/db/data/springer.msg` on our servers and should +be placed at `nomad/normalizing/data/springer.msg`. + +Thirdly, you have to provide static files to serve the docs and NOMAD distribution: +```sh +cd docs +make html +cd .. +python setup.py compile +python setup.py sdist +cp dist/nomad-lab-*.tar.gz dist/nomad-lab.tar.gz +``` + +You need to have the infrastructure partially running: elastic, rabbitmq. +The rest should be mocked or provided by the tests. Make sure that you do no run any +worker, as they will fight for tasks in the queue. +```sh +cd ops/docker-compose/infrastructure +docker-compose up -d elastic rabbitmq +cd ../.. +pytest -svx tests +``` + +We use pylint, pycodestyle, and mypy to ensure code quality. To run those: +```sh +nomad dev qa --skip-test +``` + +To run all tests and code qa: +```sh +nomad dev qa +``` + +This mimiques the tests and checks that the GitLab CI/CD will perform. + + +## Setup your (I)DE + +The documentation section on development guidelines details how the code is organized, +tested, formatted, and documented. To help you meet these guidelines, we recomment to +use a proper IDE for development and ditch any VIM/Emacs (mal-)practices. + +### Visual Studio Code + +Here are some VSCode settings that will enable features for linting, some auto formating, +line size ruler, etc. +```json +{ + "python.venvPath": "${workspaceFolder}/.pyenv", + "python.pythonPath": "${workspaceFolder}/.pyenv/bin/python", + "git.ignoreLimitWarning": true, + "editor.rulers": [90], + "editor.renderWhitespace": "all", + "editor.tabSize": 4, + "[javascript]": { + "editor.tabSize": 2 + }, + "files.trimTrailingWhitespace": true, + "git.enableSmartCommit": true, + "eslint.autoFixOnSave": true, + "python.linting.pylintArgs": [ + "--load-plugins=pylint_mongoengine,nomad/metainfo/pylint_plugin", + ], + "python.linting.pep8Path": "pycodestyle", + "python.linting.pep8Enabled": true, + "python.linting.pep8Args": ["--ignore=E501,E701"], + "python.linting.mypyEnabled": true, + "python.linting.mypyArgs": [ + "--ignore-missing-imports", + "--follow-imports=silent", + "--no-strict-optional" + ], + "workbench.colorCustomizations": { + "editorError.foreground": "#FF2222", + "editorOverviewRuler.errorForeground": "#FF2222", + "editorWarning.foreground": "#FF5500", + "editorOverviewRuler.warningForeground": "#FF5500", + "activityBar.background": "#4D2111", + "titleBar.activeBackground": "#6B2E18", + "titleBar.activeForeground": "#FDF9F7" + }, + "files.watcherExclude": { + "**/.git/objects/**": true, + "**/.git/subtree-cache/**": true, + "**/node_modules/*/**": true, + "**/.pyenv/*/**": true, + "**/__pycache__/*/**": true, + "**/.mypy_cache/*/**": true, + "**/.volumes/*/**": true, + "**/docs/.build/*/**": true + } +} +``` + +Here are some example launch configs for VSCode: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}/gui" + }, + { + "name": "Python: API Flask (0.11.x or later)", + "type": "python", + "request": "launch", + "module": "flask", + "env": { + "FLASK_APP": "nomad/app/__init__.py" + }, + "args": [ + "run", + "--port", + "8000", + "--no-debugger", + "--no-reload" + ] + }, + { + "name": "Python: some test", + "type": "python", + "request": "launch", + "cwd": "${workspaceFolder}", + "program": "${workspaceFolder}/.pyenv/bin/pytest", + "args": [ + "-sv", + "tests/test_cli.py::TestClient::test_mirror" + ] + }, + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}" + }, + { + "name": "Python: Attach", + "type": "python", + "request": "attach", + "localRoot": "${workspaceFolder}", + "remoteRoot": "${workspaceFolder}", + "port": 3000, + "secret": "my_secret", + "host": "localhost" + } + ] +} +``` + +## Code guidelines + +### Design principles + +- simple first, complicated only when necessary +- adopting generic established 3rd party solutions before implementing specific solutions +- only uni directional dependencies between components/modules, no circles +- only one language: Python (except, GUI of course) + +### Rules + +The are some *rules* or better strong *guidelines* for writing code. The following +applies to all python code (and were applicable, also to JS and other code): + +- Use an IDE (e.g. [vscode](https://code.visualstudio.com/) or otherwise automatically + enforce code ([formatting and linting](https://code.visualstudio.com/docs/python/linting)). + Use `nomad qa` before committing. This will run all tests, static type checks, linting, etc. + +- There is a style guide to python. Write [pep-8](https://www.python.org/dev/peps/pep-0008/) + compliant python code. An exception is the line cap at 79, which can be broken but keep it 90-ish. + +- Test the public API of each sub-module (i.e. python file) + +- Be [pythonic](https://docs.python-guide.org/writing/style/) and watch + [this](https://www.youtube.com/watch?v=wf-BqAjZb8M). + +- Document any *public* API of each sub-module (e.g. python file). Public meaning API that + is exposed to other sub-modules (i.e. other python files). + +- Use google [docstrings](http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html). + +- Add your doc-strings to the sphinx documentation in `docs`. Use .md, follow the example. + Markdown in sphinx is supported via [recommonmark] + (https://recommonmark.readthedocs.io/en/latest/index.html#autostructify) + and [AutoStructify](http://recommonmark.readthedocs.io/en/latest/auto_structify.html) + +- The project structure is according to [this guide](https://docs.python-guide.org/writing/structure/). + Keep it! + +- Write tests for all contributions. + + +### Enforcing Rules: CI/CD + + +These *guidelines* are partially enforced by CI/CD. As part of CI all tests are run on all +branches; further we run a *linter*, *pep8* checker, and *mypy* (static type checker). You can +run `nomad qa` to run all these tests and checks before committing. + +The CI/CD will run on all refs that do not start with `dev-`. The CI/CD will +not release or deploy anything automatically, but it can be manually triggered after the +build and test stage completed successfully. + +### Names and identifiers + +There are is some terminology consistently used in this documentation and the source +code. Use this terminology for identifiers. + +Do not use abbreviations. There are (few) exceptions: `proc` (processing); `exc`, `e` (exception); +`calc` (calculation), `repo` (repository), `utils` (utilities), and `aux` (auxiliary). +Other exceptions are `f` for file-like streams and `i` for index running variables. +Btw., the latter is almost never necessary in python. + +Terms: + +- upload: A logical unit that comprises one (.zip) file uploaded by a user. +- calculation: A computation in the sense that is was created by an individual run of a CMS code. +- raw file: User uploaded files (e.g. part of the uploaded .zip), usually code input or output. +- upload file/uploaded file: The actual (.zip) file a user uploaded +- mainfile: The mainfile output file of a CMS code run. +- aux file: Additional files the user uploaded within an upload. +- repo entry: Some quantities of a calculation that are used to represent that calculation in the repository. +- archive data: The normalized data of one calculation in nomad's meta-info-based format. + +Throughout nomad, we use different ids. If something +is called *id*, it is usually a random uuid and has no semantic connection to the entity +it identifies. If something is called a *hash* than it is a hash build based on the +entity it identifies. This means either the whole thing or just some properties of +said entities. + +- The most common hashes is the `calc_hash` based on mainfile and auxfile contents. +- The `upload_id` is a UUID assigned at upload time and never changed afterwards. +- The `mainfile` is a path within an upload that points to a main code output file. + Since, the upload directory structure does not change, this uniquely ids a calc within the upload. +- The `calc_id` (internal calculation id) is a hash over the `mainfile` and respective + `upload_id`. Therefore, each `calc_id` ids a calc on its own. +- We often use pairs of `upload_id/calc_id`, which in many context allow to resolve a calc + related file on the filesystem without having to ask a database about it. +- The `pid` or (`coe_calc_id`) is an sequential interger id. +- Calculation `handle` or `handle_id` are created based on those `pid`. + To create hashes we use :py:func:`nomad.utils.hash`. + + +### Logging + +There are three important prerequisites to understand about nomad-FAIRDI's logging: + +- All log entries are recorded in a central elastic search database. To make this database + useful, log entries must be sensible in size, frequence, meaning, level, and logger name. + Therefore, we need to follow some rules when it comes to logging. +- We use an *structured* logging approach. Instead of encoding all kinds of information + in log messages, we use key-value pairs that provide context to a log *event*. In the + end all entries are stored as JSON dictionaries with `@timestamp`, `level`, + `logger_name`, `event` plus custom context data. Keep events very short, most + information goes into the context. +- We use logging to inform about the state of nomad-FAIRDI, not about user + behavior, input, data. Do not confuse this when determining the log-level for an event. + For example, a user providing an invalid upload file, for example, should never be an error. + +Please follow the following rules when logging: + +- If a logger is not already provided, only use + :py:func:`nomad.utils.get_logger` to acquire a new logger. Never use the + build-in logging directly. These logger work like the system loggers, but + allow you to pass keyword arguments with additional context data. See also + the [structlog docs](https://structlog.readthedocs.io/en/stable/). +- In many context, a logger is already provided (e.g. api, processing, parser, normalizer). + This provided logger has already context information bounded. So it is important to + use those instead of acquiring your own loggers. Have a look for methods called + `get_logger` or attributes called `logger`. +- Keep events (what usually is called *message*) very short. Examples are: *file uploaded*, + *extraction failed*, etc. +- Structure the keys for context information. When you analyse logs in ELK, you will + see that the set of all keys over all log entries can be quit large. Structure your + keys to make navigation easier. Use keys like `nomad.proc.parser_version` instead of + `parser_version`. Use module names as prefixes. +- Don't log everything. Try to anticipate, how you would use the logs in case of bugs, + error scenarios, etc. +- Don't log sensitive data. +- Think before logging data (especially dicts, list, numpy arrays, etc.). +- Logs should not be abused as a *printf*-style debugging tool. + +The following keys are used in the final logs that are piped to Logstash. +Notice that the key name is automatically formed by a separate formatter and +may differ from the one used in the actual log call. + +Keys that are autogenerated for all logs: + + - `@timestamp`: Timestamp for the log + - `@version`: Version of the logger + - `host`: The host name from which the log originated + - `path`: Path of the module from which the log was created + - `tags`: Tags for this log + - `type`: The *message_type* as set in the LogstashFormatter + - `level`: The log level: `DEBUG`, `INFO`, `WARNING`, `ERROR` + - `logger_name`: Name of the logger + - `nomad.service`: The service name as configured in `config.py` + - `nomad.release`: The release name as configured in `config.py` + +Keys that are present for events related to processing an entry: + + - `nomad.upload_id`: The id of the currently processed upload + - `nomad.calc_id`: The id of the currently processed entry + - `nomad.mainfile`: The mainfile of the currently processed entry + +Keys that are present for events related to exceptions: + + - `exc_info`: Stores the full python exception that was encountered. All + uncaught exceptions will be stored automatically here. + - `digest`: If an exception was raised, the last 256 characters of the message + are stored automatically into this key. If you wish to search for exceptions + in Kibana, you will want to use this value as it will be indexed unlike the + full exception object. + + +### Copyright Notices + +We follow this [recommendation](https://www.linuxfoundation.org/blog/2020/01/copyright-notices-in-open-source-software-projects/) +of the Linux Foundation for the copyright notice that is placed on top of each source +code file. + +It is intended to provide a broad generic statement that allows all authors/contributors +of the NOMAD project to claim their copyright, independent of their organization or +individual ownership. + +You can simply copy the notice from another file. From time to time we can use a tool +like [licenseheaders](https://pypi.org/project/licenseheaders/) to ensure correct +notices. In addition we keep an purely informative AUTHORS file. + + +## Git/GitLab + +### Branches and clean version history + +The `master` branch of our repository is *protected*. You must not (even if you have +the rights) commit to it directly. The `master` branch references the latest official +release (i.e. what the current NOMAD runs on). The current development is represented by +*version* branches, named `vx.x.x`. Usually there are two or more of these branched, +representing the development on *minor/bugfix* versions and the next *major* version(s). +Ideally these *version* branches are also not manually push to. + +Instead you develop +on *feature* branches. These are branches that are dedicated to implement a single feature. +They are short lived and only exist to implement a single feature. + +The lifecycle of a *feature* branch should look like this: + +- create the *feature* branch from the last commit on the respective *version* branch that passes CI + +- do your work and push until you are satisfied and the CI passes + +- create a merge request on GitLab + +- discuss the merge request on GitLab + +- continue to work (with the open merge request) until all issues from the discussion are resolved + +- the maintainer performs the merge and the *feature* branch gets deleted + +While working on a feature, there are certain practices that will help us to create +a clean history with coherent commits, where each commit stands on its own. + +```sh + git commit --amend +``` + +If you committed something to your own feature branch and then realize by CI that you have +some tiny error in it that you need to fix, try to amend this fix to the last commit. +This will avoid unnecessary tiny commits and foster more coherent single commits. With *amend* +you are basically adding changes to the last commit, i.e. editing the last commit. If +you push, you need to force it `git push origin feature-branch --force-with-lease`. So be careful, and +only use this on your own branches. + +```sh + git rebase +``` + +Lets assume you work on a bigger feature that takes more time. You might want to merge +the version branch into your feature branch from time to time to get the recent changes. +In these cases, use rebase and not merge. Rebase puts your branch commits in front of the +merged commits instead of creating a new commit with two ancestors. It basically moves the +point where you initially branched away from the version branch to the current position in +the version branch. This will avoid merges, merge commits, and generally leave us with a +more consistent history. You can also rebase before create a merge request, basically +allowing for no-op merges. Ideally the only real merges that we ever have, are between +version branches. + +```sh + git merge --squash +``` + +When you need multiple branches to implement a feature and merge between them, try to +use *squash*. Squashing basically puts all commits of the merged branch into a single commit. +It basically allows you to have many commits and then squash them into one. This is useful +if these commits where just made for synchronization between workstations or due to +unexpected errors in CI/CD, you needed a save point, etc. Again the goal is to have +coherent commits, where each commits makes sense on its own. + +Often a feature is also represented by an *issue* on GitLab. Please mention the respective +issues in your commits by adding the issue id at the end of the commit message: *My message. #123*. + +We tag releases with `vX.X.X` according to the regular semantic versioning practices. +After releasing and tagging the *version* branch is removed. Do not confuse tags with *version* branches. +Remember that tags and branches are both Git references and you can accidentally pull/push/checkout a tag. + +The main NOMAD GitLab-project (`nomad-fair`) uses Git-submodules to maintain its +parsers and other dependencies. All these submodules are places in the `/dependencies` +directory. There are helper scripts to install (`./dependencies.sh` and +commit changes to all submodules (`./dependencies-git.sh`). After merging or checking out, +you have to make sure that the modules are updated to not accidentally commit old +submodule commits again. Usually you do the following to check if you really have a +clean working directory. + +```sh + git checkout something-with-changes + git submodule update + git status +``` + +### Submodules + +We currently use git submodules to manage NOMAD internal dependencies (e.g. parsers). +All dependencies are python packages and installed via pip to your python environement. + +This allows us to target (e.g. install) individual commits. More importantly, we can address c +ommit hashes to identify exact parser/normalizer versions. On the downside, common functions +for all dependencies (e.g. the python-common package, or nomad_meta_info) cannot be part +of the nomad-FAIRDI project. In general, it is hard to simultaneously develop nomad-FAIRDI +and NOMAD-coe dependencies. + +Another approach is to integrate the NOMAD-coe sources with nomad-FAIRDI. The lacking +availability of individual commit hashes, could be replaces with hashes of source-code +files. + +We use the `master` branch on all dependencies. Of course feature branches can be used on +dependencies to manage work in progress. diff --git a/docs/gui.rst b/docs/gui.rst deleted file mode 100644 index 822c4acb9c12de3a2ed41761dcb2e7789d9ca453..0000000000000000000000000000000000000000 --- a/docs/gui.rst +++ /dev/null @@ -1,7 +0,0 @@ -GUI React Components -==================== - -These is the API reference for NOMAD's GUI React components. - -.. contents:: Table of Contents -.. reactdocgen:: react-docgen.out diff --git a/docs/index.rst b/docs/index.rst index 910deca675c689954ced9d65b978a0ea00d005fa..96c39c3b9b91194323670c19f5ddc0501de42260 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -5,18 +5,64 @@ This project is a prototype for the continuation of the original NOMAD-coe softw and infrastructure with a simplyfied architecture and consolidated code base. .. toctree:: - :maxdepth: 2 + :maxdepth: 1 introduction.md upload.rst - api_tutorial.md + api.md client/client.rst metainfo.rst archive.rst + developers.md + parser.md + normalizer.rst + oasis.rst ops/ops.rst - dev/setup.md - dev/dev_guidelines.rst - dev/parser_tutorial.md - dev/normalizer.rst - api.rst - reference.rst + api_reference.rst + python_reference.rst + +.. # Introduction +.. # Repository, Encyclopedia, etc. +.. # Interfaces: GUIs and APIs +.. # Technical architecture +.. # History +.. # How to upload data +.. # Prepare your files +.. # Upload your files +.. # Publish you files +.. # How to use NOMAD APIs +.. # The different APIs +.. # curl +.. # requests +.. # bravado +.. # NOMAD's Python library +.. # Getting started +.. # Command line interface (CLI) +.. # Run parsers and normalizers +.. # Data format (Metainfo) +.. # Introduction +.. # Browsing the Metainfo +.. # Getting started +.. # Quantities +.. # Sections +.. # Reference +.. # Data access (Archive) +.. # Introduction +.. # Browsing the Archive +.. # Getting started +.. # Develop NOMAD +.. # Getting started +.. # Running NOMAD +.. # Running tests +.. # Style guide +.. # VS code +.. # GIT +.. # How to write a parser +.. # Getting started +.. # Text files +.. # XML parser +.. # How to write a normalizer +.. # Operating a NOMAD OASIS +.. # Operating NOMAD (with k8s) +.. # API Reference +.. # Python Reference diff --git a/docs/metainfo.rst b/docs/metainfo.rst index 4cc884d3723de14a3d71ebe6c858fadf91af2f6c..737962bc07f3bc8e83481a9fed1533e0ca2961cb 100644 --- a/docs/metainfo.rst +++ b/docs/metainfo.rst @@ -1,7 +1,7 @@ .. _metainfo-label: -NOMAD Metainfo -============== +Data schema (Metainfo) +====================== Introduction ------------ @@ -67,6 +67,7 @@ Python modules: from nomad.datamodel.metainfo.public import section_run my_run = section_run() + Many more examples about how to read the NOMAD Metainfo programmatically can be found `here `_. diff --git a/docs/dev/normalizer.rst b/docs/normalizer.rst similarity index 100% rename from docs/dev/normalizer.rst rename to docs/normalizer.rst diff --git a/docs/oasis.rst b/docs/oasis.rst new file mode 100644 index 0000000000000000000000000000000000000000..3e31876359d638c475a58973dbfbd27a3c7dd32b --- /dev/null +++ b/docs/oasis.rst @@ -0,0 +1 @@ +.. mdinclude:: ../ops/docker-compose/nomad-oasis/README.md diff --git a/docs/ops/depl_images.rst b/docs/ops/depl_images.rst deleted file mode 100644 index 39b74eff4dc7bd63eab679d82679e7120a8270db..0000000000000000000000000000000000000000 --- a/docs/ops/depl_images.rst +++ /dev/null @@ -1 +0,0 @@ -.. mdinclude:: ../../ops/containers/README.md diff --git a/docs/ops/oasis.rst b/docs/ops/oasis.rst deleted file mode 100644 index 217ce1a9f2ef3eb5c20e22e8d85e596431bedda4..0000000000000000000000000000000000000000 --- a/docs/ops/oasis.rst +++ /dev/null @@ -1 +0,0 @@ -.. mdinclude:: ../../ops/docker-compose/nomad-oasis/README.md diff --git a/docs/ops/ops.rst b/docs/ops/ops.rst index 9f3025fbf1d75cadb672c1c49d87d40957b3ea5c..be731f26068b36d656a16b35ef024e520e5c2331 100644 --- a/docs/ops/ops.rst +++ b/docs/ops/ops.rst @@ -1,10 +1,8 @@ -Operating NOMAD/OASIS -##################### +Operating NOMAD +############### .. toctree:: :maxdepth: 2 depl_docker.rst depl_helm.rst - depl_images.rst - oasis.rst diff --git a/docs/dev/parser_tutorial.md b/docs/parser.md similarity index 59% rename from docs/dev/parser_tutorial.md rename to docs/parser.md index 48ff903db5872836346625ffa617ef7afa011a8c..c2c465bdcf5168f0aa66a4d4eaf8c3863b13d3af 100644 --- a/docs/dev/parser_tutorial.md +++ b/docs/parser.md @@ -1,25 +1,351 @@ # How to write a parser -## The parser project +NOMAD uses parsers to convert raw code input and output files into NOMAD's common +Archive format. This is documentation on how to develop such a parser. -First copy an existing parser project as a template. E.g. the vasp parser. Change -the parser metadata in ``setup.py``. You can already install it with ``-e``: from -the main dir of the new parser: +## Getting started +Let's assume we need to write a new parser from scratch. + +First we need the install *nomad-lab* Python package to get the necessary libraries: +```sh +pip install nomad-lab ``` -pip install -e . + +We prepared an example parser project that you can work with. +```sh +git clone https://github.com/nomad-coe/nomad-parser-example.git --branch hello-world ``` +Alternatively, you can fork the example project on GitHub to create your own parser. Clone +your fork accordingly. + The project structure should be +```none +example/exampleparser/__init__.py +example/exampleparser/__main__.py +example/exampleparser/metainfo.py +example/exampleparser/parser.py +example/LICENSE.txt +example/README.md +example/setup.py +``` + +Next you should install your new parser with pip. The `-e` parameter installs the parser +in *development*. This means you can change the sources without the need to re-install. +```sh +cd example +pip install -e . +``` + +The main code file `exampleparser/parser.py` should look like this: +```python +class ExampleParser(FairdiParser): + def __init__(self): + super().__init__(name='parsers/example', code_name='EXAMPLE') + + def run(self, mainfile: str, archive: EntryArchive, logger): + # Log a hello world, just to get us started. TODO remove from an actual parser. + logger.info('Hello World') + + run = archive.m_create(Run) + run.program_name = 'EXAMPLE' +``` + +A parser is a simple program with a single class in it. The base class `FairdiParser` +provides the necessary interface to NOMAD. We provide some basic information +about our parser in the constructor. The *main* function `run` simply takes a filepath +and empty archive as input. Now its up to you, to open the given file and populate the +given archive accordingly. In the plain *hello world*, we simple create a log entry and +populate the archive with a *root section* `Run` and set the program name to `EXAMPLE`. + +You can run the parser with the included `__main__.py`. It takes a file as argument and +you can run it like this: +```sh +python -m exampleparser test/data/example.out +``` + +The output should show the log entry and the minimal archive with one `section_run` and +the respective `program_name`. +```json +INFO root 2020-12-02T11:00:52 Hello World + - nomad.release: devel + - nomad.service: unknown nomad service +{ + "section_run": [ + { + "program_name": "EXAMPLE" + } + ] +} +``` + +## Parsing test files + +Let's do some actual parsing. Here we demonstrate how to parse ASCII files with some +structure information in it. As it is typically used by materials science codes. + +The on the `master` branch of the example project, we have a more 'realistic' example: +```sh +git checkout master +``` + +This example imagines a potential code output that looks like this (`tests/data/example.out`): +```none +2020/05/15 + *** super_code v2 *** + +system 1 +-------- +sites: H(1.23, 0, 0), H(-1.23, 0, 0), O(0, 0.33, 0) +latice: (0, 0, 0), (1, 0, 0), (1, 1, 0) +energy: 1.29372 + +*** This was done with magic source *** +*** x°42 *** + + +system 2 +-------- +sites: H(1.23, 0, 0), H(-1.23, 0, 0), O(0, 0.33, 0) +cell: (0, 0, 0), (1, 0, 0), (1, 1, 0) +energy: 1.29372 +``` + +There is some general information at the top and then a list of simulated systems with +sites and lattice describing crystal structures, a computed energy value, an example for +a code specific quantity from a 'magic source'. + +In order to convert the information from this file into the archive, we first have to +parse the necessary quantities: the date, system, energy, etc. The *nomad-lab* Python +package provides a `text_parser` module for declarative text file parsing. You can +define text file parsers like this: +```python +def str_to_sites(string): + sym, pos = string.split('(') + pos = np.array(pos.split(')')[0].split(',')[:3], dtype=float) + return sym, pos + + +calculation_parser = UnstructuredTextFileParser(quantities=[ + Quantity('sites', r'([A-Z]\([\d\.\, \-]+\))', str_operation=str_to_sites), + Quantity( + System.lattice_vectors, + r'(?:latice|cell): \((\d)\, (\d), (\d)\)\,?\s*\((\d)\, (\d), (\d)\)\,?\s*\((\d)\, (\d), (\d)\)\,?\s*', + repeats=False), + Quantity('energy', r'energy: (\d\.\d+)'), + Quantity('magic_source', r'done with magic source\s*\*{3}\s*\*{3}\s*[^\d]*(\d+)', repeats=False)]) + +mainfile_parser = UnstructuredTextFileParser(quantities=[ + Quantity('date', r'(\d\d\d\d\/\d\d\/\d\d)', repeats=False), + Quantity('program_version', r'super\_code\s*v(\d+)\s*', repeats=False), + Quantity( + 'calculation', r'\s*system \d+([\s\S]+?energy: [\d\.]+)([\s\S]+\*\*\*)*', + sub_parser=calculation_parser, + repeats=True) +]) +``` + +The quantities to be parsed can be specified as a list of `Quantity` objects with a name +and a *regular expression* (re) pattern. The matched value should be enclosed in a group(s) +denoted by `(...)`. +By default, the parser uses the findall method of `re`, hence overlap +between matches is not tolerated. If overlap cannot be avoided, one should switch to the +finditer method by passing *findall=False* to the parser. Multiple +matches for the quantity are returned if *repeats=True* (default). The name, data type, +shape and unit for the quantity can also intialized by passing a metainfo Quantity. +An external function *str_operation* can be also be passed to perform more specific +string operations on the matched value. A local parsing on a matched block can be carried +out by nesting a *sub_parser*. This is also an instance of the `UnstructuredTextFileParser` +with a list of quantities to parse. To access a parsed quantity, one can use the *get* +method. + +We can apply these parser definitions like this: +```sh +mainfile_parser.mainfile = mainfile +mainfile_parser.parse() +``` + +This will populate the `mainfile_parser` object with parsed data and it can be accessed +like a Python dict with quantity names as keys: +```python +run = archive.m_create(Run) +run.program_name = 'super_code' +run.program_version = str(mainfile_parser.get('program_version')) +date = datetime.datetime.strptime( + mainfile_parser.get('date'), + '%Y/%m/%d') - datetime.datetime(1970, 1, 1) +run.program_compilation_datetime = date.total_seconds() + +for calculation in mainfile_parser.get('calculation'): + system = run.m_create(System) + + system.lattice_vectors = calculation.get('lattice_vectors') + sites = calculation.get('sites') + system.atom_labels = [site[0] for site in sites] + system.atom_positions = [site[1] for site in sites] + + scc = run.m_create(SCC) + scc.single_configuration_calculation_to_system_ref = system + scc.energy_total = calculation.get('energy') * units.eV + scc.single_configuration_calculation_to_system_ref = system + magic_source = calculation.get('magic_source') + if magic_source is not None: + scc.x_example_magic_value = magic_source +``` + +You can still run the parse on the given example file: +```sh +python -m exampleparser test/data/example.out +``` + +Now you should get a more comprehensive archive with all the provided information from +the `example.out` file. + +** TODO more examples an explanations for: unit conversion, logging, types, scalar, vectors, +multi-line matrices ** + +## Extending the Metainfo +The NOMAD Metainfo defines the schema of each archive. There are pre-defined schemas for +all domains (e.g. `common_dft.py` for electron-structure codes; `common_ems.py` for +experiment data, etc.). The sections `Run`, `System`, an single configuration calculations (`SCC`) +in the example are taken fom `common_dft.py`. While this covers most data that is usually +provide in code input/output files, some data is typically format specific and only applies +to a certain code or method. For these cases, we allow to extend the Metainfo like +this (`exampleparser/metainfo.py`): +```python +# We extend the existing common definition of a section "single configuration calculation" +class ExampleSCC(SCC): + # We alter the default base class behavior to add all definitions to the existing + # base class instead of inheriting from the base class + m_def = Section(extends_base_section=True) + + # We define an additional example quantity. Use the prefix x__ to denote + # non common quantities. + x_example_magic_value = Quantity(type=int, description='The magic value from a magic source.') +``` + +## Testing a parser + +Until now, we simply run our parse on some example data and manually observed the output. +To improve the parser quality and ease the further development, you should get into the +habit of testing the parser. + +We use the Python unit test framework *pytest*: +```sh +pip install pytest +``` + +A typical test, would take one example file, parse it, and make assertions about +the output. +```python +def test_example(): + parser = rExampleParser() + archive = EntryArchive() + parser.run('test/data/example.out', archive, logging) + + run = archive.section_run[0] + assert len(run.section_system) == 2 + assert len(run.section_single_configuration_calculation) == 2 + assert run.section_single_configuration_calculation[0].x_example_magic_value == 42 +``` + +You can run all tests in the `tests` directory like this: +```sh +pytest -svx tests +``` + +You should define individual test cases with example files that demonstrate certain +features of the underlying code/format. + +## Structured data files with numpy +**TODO: examples** + +The `DataTextFileParser` uses the numpy.loadtxt function to load an structured data file. +The loaded data can be accessed from property *data*. + +## XML Parser + +**TODO: examples** + +The `XMLParser` uses the ElementTree module to parse an xml file. The parse method of the +parser takes in an xpath style key to access individual quantities. By default, automatic +data type conversion is performed, which can be switched off by setting *convert=False*. + +## Add the parser to NOMAD + +NOMAD has to manage multiple parsers and during processing needs to decide what parsers +to run on what files. To manage parser, a few more information about parsers is necessary. + +Consider the example, where we use the `FairdiParser` constructor to add additional +attributes that determine for what files the parser is indented: +```python +class ExampleParser(FairdiParser): + def __init__(self): + super().__init__( + name='parsers/example', code_name='EXAMPLE', code_homepage='https://www.example.eu/', + mainfile_mime_re=r'(application/.*)|(text/.*)', + mainfile_contents_re=(r'^\s*#\s*This is example output')) ``` -myparser/myparser/__init__.py -myparser/test/example_file.out -myparser/LICENSE.txt -myparser/README.txt -myparser/setup.py + +- `mainfile_mime_re`: A regular expression on the mime type of files. The parser is only +run on files with matching mime type. The mime-type is *guessed* with libmagic. +- `mainfile_contents_re`: A regular expression that is applied to the first 4k of a file. +The parser is only run on files where this matches. + +The nomad infrastructure keep a list of parser objects (in `nomad/parsing/parsers.py::parsers`). +These parser are considered in the order they appear in the list. The first matching parser +is used to parse a given file. + +While each parser project should provide its own tests, a single example file should be +added to the infrastructure parser tests (`tests/parsing/test_parsing.py`). + +Once the parser is added, it become also available through the command line interface and +normalizers are applied as well: +```sh +nomad parser test/data/example.out +``` + +## Developing an existing parser +To develop an existing parser, you should install all parsers: +```sh +pip install nomad-lab[parsing] ``` -## Basic skeleton +Close the parser project on top: +```sh +git clone +cd +``` + +Either remove the installed parser and pip install the cloned version: +```sh +rm -rf /lib/python3.7/site-packages/ +pip install -e . +``` + +Or use `PYTHONPATH` so that the cloned code takes precedence over the installed code: +```sh +PYTHONPATH=. nomad parser +``` + +Alternatively, you can also do a full developer setup of the NOMAD infrastructure and +develop the parser there. + +## Legacy NOMAD-CoE parsers +During the origin NOMAD-CoE the parsing infrastructure was different. We still have +old parsers from this time in NOMAD. The key differences are: + +- different inconsistent interfaces with NOMAD, mostly via `ParserInterface` or + `mainFunction` +- more complex internal structure with interface, parser, and context classes +- no direct archive access, instead a *backend* object that takes events like + *open-section*, *set-value*, *close-section* +- *backend* communication follows a *streaming* metaphor; once an *event* is send, the + information cannot be altered anymore, the order of parsing is tight to the order of + information in the archive +- close coupling between parsing and archive writing declared in `SimpleMatcher` objects + that cover parsing and archive population at the same time The following is an example for simple almost empty skeleton for a parser. The nomad@FAIRDI infrastructure will use the ``ParserInterface`` implementation to use @@ -99,7 +425,7 @@ or if you installed your new parser in your environment python -m myparser test/example_file.out ``` -## Simple matcher +### Simple matcher The central thing in a parser using this infrastructure is the SimpleMatcher class. It is used to defines objects that matches some lines of a file and extracts some values out of them. @@ -111,7 +437,8 @@ The simplest kind of matcher looks like this ``` -This matcher uses a single regular expression ([regular expressions documentation](https://docs.python.org/2/library/re.html)) to match a line. An online tool to quickly verify regular expressions and to see what they match can be found [here](https://regex101.com/#python). +This matcher uses a single regular expression ([regular expressions documentation](https://docs.python.org/2/library/re.html)) +to match a line. Here is an online tool to quickly [verify regular expressions](https://regex101.com/#python). Note the following things: @@ -180,7 +507,7 @@ of (metaInfoName: value), unit and type conversion are not applied. Can be also * With *startReAction* you can provide a callback function that will get called when the *startReStr* is matched. The callback signature is startReAction(backend, groups). This callback can directly access any matched groups from the regex with argument *groups*. You can use this to e.g. format a line with datetime information into a standard form and push it directly to a corresponding metainfo, or do other more advanced tasks that are not possible e.g. with fixedStartValues. * Often the parsing is complex enough that you want to create an object to keep track of it and cache various flags, open files,..., to manage the various parsing that is performed. You can store this object as *superContext* of the parser. -## Nomad meta-info +### Nomad meta-info The meta-info has a central role in the parsing. It represents the conceptual model of the extracted data, every piece of information @@ -235,7 +562,7 @@ that one wants to use for interpolation. Currently there are no methods to answe and one simply has to build the datasets himself (often with scripts) to be sure that the calculations are really consistent. -## What to parse +### What to parse You should try to parse all input parameters and all lines of the output. @@ -245,7 +572,7 @@ But the other point, that is just as important is to be able of detecting when a fails and needs improvement. This is the only way to keep the parser up to date with respect to the data that is in the repository. -## Unit conversion +### Unit conversion The code independent meta info should use SI units, codes typically do not. As shown in the examples matchers can convert automatically the value matched by the @@ -282,37 +609,36 @@ register_userdefined_quantity("usrMyCodeLength", "angstrom") this call *needs* to be done before any use of that unit. The unit can then be used just like all others: add __usrMyCodeLength to the group name. -## Backend +### Backend The backend is an object can stores parsed data according to its meta-info. The class :py:class:`nomad.parsing.Backend` provides the basic backend interface. It allows to open and close sections, add values, arrays, and values to arrays. In NOMAD-coe multiple backend implementations existed to facilitate the communication of python parsers with the scala infrastructure, including caching and streaming. -## Triggers +### Triggers When a section is closed a function can be called with the backend, gIndex and the section object (that might have cached values). This is useful to perform transformations on the data parsed before emitting it. The simplest way to achieve this is to define methods called onClose and then the section name in the object that you pass as superContext. -For example ```python def onClose_section_scf_iteration(self, backend, gIndex, section): - logging.getLogger("nomadcore.parsing").info("YYYY bla gIndex %d %s", gIndex, section.simpleValues) + logging.getLogger("nomadcore.parsing").info("YYYY bla gIndex %d %s", gIndex, section.simpleValues) ``` -defines a trigger called every time an scf iteration section is closed. +This example defines a trigger called every time an scf iteration section is closed. -## Logging +### Logging You can use the standard python logging module in parsers. Be aware that all logging is stored in a database for analysis. Do not abuse the logging. -## Testing and Debugging +### Testing and Debugging You a writing a python program. You know what to do. -## Adding the parser to nomad@FAIRDI +### Adding the parser to nomad@FAIRDI First, you add your parser to the dependencies. Put it into the dependencies folder, then: ``` @@ -342,71 +668,3 @@ parser_examples = [ ('parsers/vaspoutcar', 'tests/data/parsers/vasp_outcar/OUTCAR'), ] ``` - -## FAIRDI parsers -The new fairdi parsers avoid the use of a backend and instead make use of the new metainfo -sections. The project structure is the same as above with the addition of a `metainfo` -folder - -``` -myparser/myparser/metainfo -``` -This contains a file containing the definitions and an `__init__.py`. One should refer -to `nomad.metainfo.example.py` for a guide in writing the metainfo definitions. -Consequently, the parser class implementation is modified as in the following example. - -```python -import json - -from .metainfo import m_env -from nomad.parsing.parser import MatchingParser -from nomad.datamodel.metainfo.common_experimental import section_experiment as msection_experiment -from nomad.datamodel.metainfo.common_experimental import section_data as msection_data -from nomad.datamodel.metainfo.general_experimental_method import section_method as msection_method -from nomad.datamodel.metainfo.general_experimental_sample import section_sample as msection_sample - - -class ExampleParser(MatchingParser): - def __init__(self): - super().__init__( - name='parsers/example', code_name='example', code_homepage='https://github.com/example/example', - domain='ems', mainfile_mime_re=r'(application/json)|(text/.*)', mainfile_name_re=(r'.*.example') - ) - - def run(self, filepath, logger=None): - self._metainfo_env = m_env - - with open(filepath, 'rt') as f: - data = json.load(f) - - section_experiment = msection_experiment() - - # Read general tool environment details - section_experiment.experiment_location = data.get('experiment_location') - section_experiment.experiment_facility_institution = data.get('experiment_facility_institution') - - # Read data parameters - section_data = section_experiment.m_create(msection_data) - section_data.data_repository_name = data.get('data_repository_name') - section_data.data_preview_url = data.get('data_repository_url') - - # Read parameters related to method - section_method = section_experiment.m_create(msection_method) - section_method.experiment_method_name = data.get('experiment_method') - section_method.probing_method = 'electric pulsing' - - # Read parameters related to sample - section_sample = section_experiment.m_create(msection_sample) - section_sample.sample_description = data.get('specimen_description') - section_sample.sample_microstructure = data.get('specimen_microstructure') - section_sample.sample_constituents = data.get('specimen_constitution') - - return section_experiment -``` -The parser extends the ``MatchingParser`` class which already implements the determination -of the necessary file for parsing. The main difference to the old framework is the absense -the opening and closing of sections. One only needs to create a section which can be -accessed at any point in the code. The ``run`` method should return the root section. - -Lastly, one should add an instance of the parser class in the list of parsers at -``nomad.parsing``. \ No newline at end of file diff --git a/docs/reference.rst b/docs/python_reference.rst similarity index 100% rename from docs/reference.rst rename to docs/python_reference.rst diff --git a/docs/upload.rst b/docs/upload.rst index abc9cb18f05348eb65435def29efa41650b99476..1b4b931c1326333cefa781baf67232f376ec05e5 100644 --- a/docs/upload.rst +++ b/docs/upload.rst @@ -1,6 +1,6 @@ -====================================== -Uploading Data to the NOMAD Repository -====================================== +================== +How to upload data +================== To contribute your data to the repository, please, login to our `upload page <../gui/uploads>`_ (you need to register first, if you do not have a NOMAD account yet). diff --git a/examples/external_project_upload/upload.py b/examples/external_project_upload/upload.py index 58fe1f07c41053dfd6073db4348a0f325502f3be..6185693d7cf93fcef0d0740ad25ef3a354a27cc4 100644 --- a/examples/external_project_upload/upload.py +++ b/examples/external_project_upload/upload.py @@ -10,7 +10,7 @@ import time import os.path import sys -nomad_url = 'http://labdev-nomad.esc.rzg.mpg.de/fairdi/nomad/testing/api' +nomad_url = 'http://nomad-lab.eu/prod/rae/api' user = 'leonard.hofstadter@nomad-fairdi.tests.de' password = 'password' diff --git a/examples/tutorials/api_with_archive_query.py b/examples/tutorials/api_with_archive_query.py index 9074a35245400b2ddf74130e91cd1c79fad83a5f..6c651688489efffbd9c27a1a6de09b15e414dc05 100644 --- a/examples/tutorials/api_with_archive_query.py +++ b/examples/tutorials/api_with_archive_query.py @@ -5,7 +5,7 @@ A simple example used in the NOMAD webinar API tutorial from nomad.client import ArchiveQuery query = ArchiveQuery( - url='http://labdev-nomad.esc.rzg.mpg.de/fairdi/nomad/reprocess/api', + url='http://nomad-lab.eu/prod/rae/api', query={ 'dft.code_name': 'VASP', 'atoms': ['Ti', 'O'] diff --git a/gui/.eslintrc.js b/gui/.eslintrc.js index 528b869b26922b9625c2ec5fe406fa262a355886..a7981e9aad330280cb566d3bf83ac5b2790f9409 100644 --- a/gui/.eslintrc.js +++ b/gui/.eslintrc.js @@ -15,10 +15,14 @@ module.exports = { "browser": true }, "plugins": [ - "react", "react-hooks" + "react", "react-hooks", "testing-library", "jest" ], "rules": { - "space-before-function-paren": ["error", "never"], + "space-before-function-paren": ["error", { + "asyncArrow": "always", + "named": "never", + "anonymous": "never" + }], "camelcase": [0], "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn", @@ -28,5 +32,16 @@ module.exports = { "react": { "version": "detect" } - } + }, + "overrides": [ + { + "files": [ + "**/*.spec.js", + "**/*.spec.jsx" + ], + "env": { + "jest": true + } + } + ] } \ No newline at end of file diff --git a/gui/babel.config.json b/gui/babel.config.json new file mode 100644 index 0000000000000000000000000000000000000000..1da01e57fbb7aff0ef9325eeb1c15dae0e57afb9 --- /dev/null +++ b/gui/babel.config.json @@ -0,0 +1,3 @@ +{ + "presets": ["@babel/react", "@babel/env", "next/babel", { "targets": { "node": "current" } }] +} \ No newline at end of file diff --git a/gui/package.json b/gui/package.json index 4ac43e1dc360759e8a95cefe0283e79982b4eaa2..74016a6586fa619d23fc42c59a5d25e540c55a57 100644 --- a/gui/package.json +++ b/gui/package.json @@ -1,16 +1,16 @@ { "name": "nomad-fair-gui", - "version": "0.9.7", + "version": "0.9.8", "commit": "e98694e", "private": true, "dependencies": { - "@lauri-codes/materia": "0.0.9", + "@lauri-codes/materia": "0.0.10", "@material-ui/core": "^4.0.0", "@material-ui/icons": "^4.0.0", "@material-ui/lab": "^4.0.0-alpha.49", "@navjobs/upload": "^3.1.3", "@testing-library/jest-dom": "^4.2.4", - "@testing-library/react": "^9.3.2", + "@testing-library/react": "^10.0.0", "@testing-library/user-event": "^7.1.2", "autosuggest-highlight": "^3.1.1", "base-64": "^0.1.0", @@ -62,7 +62,9 @@ "prebuild": "npm run generate-build-version", "start": "react-scripts start", "build": "react-scripts build", - "test": "react-scripts test", + "test": "react-scripts test --env=jest-environment-jsdom-sixteen --watchAll=false", + "watch-test": "react-scripts test --env=jest-environment-jsdom-sixteen", + "lint": "eslint 'src/**/*.js'", "eject": "react-scripts eject" }, "devDependencies": { @@ -71,10 +73,13 @@ "eslint": "^6.6.0", "eslint-config-standard": "^11.0.0", "eslint-plugin-import": "^2.14.0", + "eslint-plugin-jest": "^24.1.3", "eslint-plugin-node": "^8.0.1", "eslint-plugin-promise": "^3.7.0", "eslint-plugin-react": "^7.20.5", "eslint-plugin-standard": "^3.1.0", + "eslint-plugin-testing-library": "^3.10.1", + "jest-environment-jsdom-sixteen": "^1.0.3", "react-docgen": "^5.3.0", "serve": "^10.0.0" }, diff --git a/gui/public/env.js b/gui/public/env.js index 75daa4c7a98bd6d12ce9f0941935987429b1778b..750d95b2e4db033fb5249985aeb4ace9b341abf5 100644 --- a/gui/public/env.js +++ b/gui/public/env.js @@ -9,7 +9,7 @@ window.nomadEnv = { 'matomoUrl': 'https://nomad-lab.eu/fairdi/stat', 'matomoSiteId': '2', 'version': { - 'label': '0.9.7', + 'label': '0.9.8', 'isBeta': false, 'isTest': true, 'usesBetaData': true, diff --git a/gui/src/components/App.js b/gui/src/components/App.js index 19ee764e15918ae2072f1d9a5c8748f88c363965..9e7e4b3a8415f3cd29fffe7f56d280ffe51084d7 100644 --- a/gui/src/components/App.js +++ b/gui/src/components/App.js @@ -15,632 +15,49 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useEffect, useState, useContext, useCallback, useRef, useMemo } from 'react' -import PropTypes from 'prop-types' -import { compose } from 'recompose' -import classNames from 'classnames' -import { MuiThemeProvider, withStyles, makeStyles } from '@material-ui/core/styles' -import { LinearProgress, MenuList, Typography, - AppBar, Toolbar, Button, DialogContent, DialogTitle, DialogActions, Dialog, Tooltip, - Snackbar, SnackbarContent, FormGroup, FormControlLabel, Switch, IconButton, Link as MuiLink, Menu } from '@material-ui/core' -import { Route, Link, withRouter, useLocation } from 'react-router-dom' -import BackupIcon from '@material-ui/icons/Backup' -import SearchIcon from '@material-ui/icons/Search' -import UserDataIcon from '@material-ui/icons/AccountCircle' -import AboutIcon from '@material-ui/icons/Home' -import ForumIcon from '@material-ui/icons/QuestionAnswer' -import FAQIcon from '@material-ui/icons/LiveHelp' -import EncyclopediaIcon from '@material-ui/icons/Language' -import MetainfoIcon from '@material-ui/icons/Info' -import DocIcon from '@material-ui/icons/Help' -import CodeIcon from '@material-ui/icons/Code' -import TermsIcon from '@material-ui/icons/Assignment' -import UnderstoodIcon from '@material-ui/icons/Check' -import AnalyticsIcon from '@material-ui/icons/ShowChart' -import MoreIcon from '@material-ui/icons/MoreVert' -import {help as searchHelp, default as SearchPage} from './search/SearchPage' -import HelpDialog from './Help' -import { ApiProvider, withApi, apiContext } from './api' -import { ErrorSnacks, withErrors } from './errors' -import { help as entryHelp, default as EntryPage } from './entry/EntryPage' -import About from './About' -import LoginLogout from './LoginLogout' -import { guiBase, consent, nomadTheme, appBase, version, oasis, aitoolkitEnabled, encyclopediaEnabled } from '../config' -import packageJson from '../../package.json' -import {help as uploadHelp, default as UploadPage} from './uploads/UploadPage' -import ResolvePID from './entry/ResolvePID' -import DatasetPage from './DatasetPage' -import { amber } from '@material-ui/core/colors' -import {help as userdataHelp, default as UserdataPage} from './UserdataPage' -import ResolveDOI from './dataset/ResolveDOI' -import FAQ from './FAQ' -import EntryQuery from './entry/EntryQuery' -import {matomo} from '../index' -import { useCookies } from 'react-cookie' -import Markdown from './Markdown' -import { help as metainfoHelp, MetainfoPage } from './archive/MetainfoBrowser' -import AIToolkitPage from './aitoolkit/AIToolkitPage' - -export const ScrollContext = React.createContext({scrollParentRef: null}) - -function LoadingIndicator() { - const {api} = useContext(apiContext) - const [loading, setLoading] = useState(0) - const handleOnLoading = useCallback(loading => setLoading(loading), [setLoading]) - useEffect(() => { - api.onLoading(handleOnLoading) - return () => api.removeOnLoading(handleOnLoading) - }, [api, handleOnLoading]) - - return loading ? : '' -} - -export class VersionMismatch extends Error { - constructor(msg) { - super(msg) - this.name = 'VersionMismatch' - } -} - -function ReloadSnack() { - return - There is a new NOMAD version. Please press your browser's reload (or even shift+reload) button.} - /> - -} - -const useMainMenuItemStyles = makeStyles(theme => ({ - button: { - margin: theme.spacing(1), - whiteSpace: 'nowrap' - } -})) - -function MainMenuItem({tooltip, title, path, href, onClick, icon}) { - const {pathname} = useLocation() - const classes = useMainMenuItemStyles() - const selected = path === pathname || (path !== '/' && pathname.startsWith(path)) - const rest = path ? {to: path, component: Link} : {href: href} - const button = - return tooltip ? {button} : button -} -MainMenuItem.propTypes = { - 'tooltip': PropTypes.string.isRequired, - 'title': PropTypes.string.isRequired, - 'path': PropTypes.string, - 'href': PropTypes.string, - 'onClick': PropTypes.func, - 'icon': PropTypes.element.isRequired -} - -const useBetaSnackStyles = makeStyles(theme => ({ - root: {}, - snack: { - backgroundColor: amber[700] - } -})) -function BetaSnack() { - const classes = useBetaSnackStyles() - const [understood, setUnderstood] = useState(false) - - if (!version) { - console.warn('no version data available') - return '' - } - - if (!version.isBeta && !version.isTest) { - return '' - } - - return - - You are using a {version.isBeta ? 'beta' : 'test'} version of NOMAD ({version.label}). { - version.usesBetaData ? 'This version is not using the official data. Everything you upload here, might get lost.' : '' - } Click here for the official NOMAD version. - } - action={[ - setUnderstood(true)}> - - - ]} - /> - -} - -function Consent(moreProps) { - const [cookies, setCookie] = useCookies() - const [accepted, setAccepted] = useState(cookies['terms-accepted']) - const [optOut, setOptOut] = useState(cookies['tracking-enabled'] === 'false') - const cookieOptions = useMemo(() => ({ - expires: new Date(2147483647 * 1000), - path: '/' + guiBase.split('/').slice(1).join('/') - }), []) - - useEffect(() => { - if (!optOut) { - matomo.push(['setConsentGiven']) - } else { - matomo.push(['requireConsent']) - } - }) - - // Write again to push forwards Safari's hard-coded 7 days ITP window - useEffect(() => { - setCookie('terms-accepted', cookies['terms-accepted'], cookieOptions) - setCookie('tracking-enabled', cookies['tracking-enabled'], cookieOptions) - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - []) - - const handleClosed = accepted => { - if (accepted) { - setCookie('terms-accepted', true, cookieOptions) - setCookie('tracking-enabled', !optOut, cookieOptions) - setAccepted(true) - } - } - const handleOpen = () => { - setCookie('terms-accepted', false, cookieOptions) - setAccepted(false) - } - +import React from 'react' +import { Router, Route } from 'react-router-dom' +import { QueryParamProvider } from 'use-query-params' +import history from '../history' +import PiwikReactRouter from 'piwik-react-router' +import { nomadTheme, matomoEnabled, matomoUrl, matomoSiteId, keycloakBase, keycloakRealm, + keycloakClientId } from '../config' +import Keycloak from 'keycloak-js' +import { KeycloakProvider } from 'react-keycloak' +import { MuiThemeProvider } from '@material-ui/core/styles' +import { ApiProvider } from './api' +import { ErrorSnacks } from './errors' +import Navigation from './nav/Navigation' + +export const matomo = matomoEnabled ? PiwikReactRouter({ + url: matomoUrl, + siteId: matomoSiteId, + clientTrackerName: 'stat.js', + serverTrackerName: 'stat' +}) : [] + +// matomo.push('requireConsent') + +const keycloak = Keycloak({ + url: keycloakBase, + realm: keycloakRealm, + clientId: keycloakClientId +}) + +export default function App() { return ( - - } - {...moreProps} - /> - - Terms of Use - - {consent} - - { - setOptOut(!optOut) - }} - color="primary" - />} - label="Do not provide information about your use of NOMAD (opt-out)." - /> - - - - - - - - ) -} - -function MoreMenu(props) { - const [anchor, setAnchor] = useState(false) - const handleClose = () => setAnchor(null) - return - setAnchor(e.currentTarget)} - icon={} /> - - } - /> - } - /> - } - /> - } - /> - - -} - -const useMainMenuStyles = makeStyles(theme => ({ - root: { - display: 'inline-flex', - padding: 0, - width: '100%', - backgroundColor: 'white' - } -})) - -function MainMenu() { - const classes = useMainMenuStyles() - - // We keep the URL of those path where components keep meaningful state in the URL. - // If the menu is used to comeback, the old URL is used. Therefore, it appears as - // if the same component instance with the same state is still there. - const {pathname, search} = useLocation() - const historyRef = useRef({ - search: '/search', - userdata: '/userdata' - }) - const history = {...historyRef.current} - Object.keys(historyRef.current).forEach(key => { - if (pathname.startsWith('/' + key)) { - historyRef.current[key] = pathname + (search || '') - history[key] = '/' + key - } - }) - - return - } - /> - } - /> - } - /> - {encyclopediaEnabled && } - />} - {!oasis && aitoolkitEnabled && } - />} - } - /> - } - /> - - - -} - -class NavigationUnstyled extends React.Component { - static propTypes = { - classes: PropTypes.object.isRequired, - children: PropTypes.any, - location: PropTypes.object.isRequired, - raiseError: PropTypes.func.isRequired - } - - static styles = theme => ({ - root: { - minWidth: 1024 - }, - title: { - marginLeft: theme.spacing(1), - flexGrow: 1, - display: 'flex', - alignItems: 'center', - alignContent: 'flex-start', - color: theme.palette.primary.main - }, - appFrame: { - zIndex: 1, - overflow: 'hidden', - position: 'relative', - display: 'flex', - width: '100%', - height: '100vh' - }, - appBar: { - zIndex: theme.zIndex.drawer + 1, - backgroundColor: 'white' - }, - menuButton: { - marginLeft: theme.spacing(1) - }, - helpButton: { - marginLeft: theme.spacing(1) - }, - hide: { - display: 'none' - }, - toolbar: { - paddingRight: theme.spacing(3) - }, - logo: { - height: theme.spacing(7), - marginRight: theme.spacing(2) - }, - content: { - marginTop: theme.spacing(13), - flexGrow: 1, - backgroundColor: theme.palette.background.default, - width: '100%', - overflow: 'auto' - }, - link: { - textDecoration: 'none', - color: theme.palette.text.primary - }, - menuItemIcon: { - marginRight: 0 - }, - barActions: { - display: 'flex', - alignItems: 'center' - }, - barSelect: { - color: `${theme.palette.getContrastText(theme.palette.primary.main)} !important` - }, - barButton: { - borderColor: theme.palette.getContrastText(theme.palette.primary.main), - marginRight: 0 - } - }) - - constructor(props) { - super(props) - this.scroll = { - scrollParentRef: null - } - this.state = { - open: false - } - } - - toolbarTitles = { - '/': 'About, Documentation, Getting Help', - '/faq': 'Frequently Asked Questions', - '/search': 'Find and Download Data', - '/uploads': 'Upload and Publish Data', - '/userdata': 'Manage Your Data', - '/metainfo': 'The NOMAD Meta Info', - '/entry': 'Entry', - '/dataset': 'Dataset', - '/aitoolkit': 'Artificial Intelligence Toolkit' - } - - toolbarHelp = { - '/': null, - '/search': {title: 'How to find and download data', content: searchHelp}, - '/uploads': {title: 'How to upload data', content: uploadHelp}, - '/userdata': {title: 'How to manage your data', content: userdataHelp}, - '/metainfo': {title: 'About the NOMAD meta-info', content: metainfoHelp}, - '/entry': {title: 'The entry page', content: entryHelp} - } - - componentDidMount() { - fetch(`${guiBase}/meta.json`, { - method: 'GET', - cache: 'no-cache', - headers: { - 'Pragma': 'no-cache', - 'Cache-Control': 'no-cache, no-store' - } - }).then((response) => response.json()) - .then((meta) => { - if (meta.commit !== packageJson.commit) { - console.log('GUI API version mismatch') - this.setState({showReloadSnack: true}) - } - }) - .catch(() => { - console.log('Could not validate version, continue...') - }) - } - - handleDrawerEvent(isOpen) { - this.setState({ open: !isOpen, openIsSet: true }) - } - - render() { - const { classes, children, location: { pathname } } = this.props - const { toolbarHelp, toolbarTitles } = this - const { showReloadSnack } = this.state - - const selected = dct => { - const key = Object.keys(dct).find(key => { - return key === pathname || (key.length > 1 && pathname.startsWith(key)) - }) - return dct[key] - } - - const theme = nomadTheme - const help = selected(toolbarHelp) - - return ( -
-
- - { showReloadSnack ? : ''} - - -
- - The NOMAD logo - - - {selected(toolbarTitles)} - - {help ? : ''} -
-
- -
-
- - -
- -
{ this.scroll.scrollParentRef = ref }}> - - {children} - -
- + }> + + + + + + + + -
-
- ) - } -} - -const Navigation = compose(withRouter, withErrors, withApi(false), withStyles(NavigationUnstyled.styles))(NavigationUnstyled) - -const routes = { - 'about': { - exact: true, - path: '/', - component: About - }, - 'faq': { - exact: true, - path: '/faq', - component: FAQ - }, - 'search': { - exact: true, - path: '/search', - component: SearchPage - }, - 'userdata': { - exact: true, - path: '/userdata', - component: UserdataPage - }, - 'entry': { - path: '/entry/id', - component: EntryPage - }, - 'entry_query': { - exact: true, - path: '/entry/query', - component: EntryQuery - }, - 'entry_pid': { - path: '/entry/pid', - component: ResolvePID - }, - 'dataset': { - path: '/dataset/id', - component: DatasetPage - }, - 'dataset_doi': { - path: '/dataset/doi', - component: ResolveDOI - }, - 'uploads': { - exact: true, - path: '/uploads', - component: UploadPage - }, - 'metainfo': { - path: '/metainfo', - component: MetainfoPage - }, - 'aitoolkit': { - path: '/aitoolkit', - component: AIToolkitPage - } -} - -class App extends React.PureComponent { - render() { - return ( - - - - - - {Object.keys(routes).map(routeKey => { - const route = routes[routeKey] - const { path, exact } = route - return props.match && } - /> - })} - - - - - ) - } + + + + ) } - -const AppWithRouter = withRouter(App) -export default AppWithRouter diff --git a/gui/src/components/aitoolkit/AIToolkitPage.js b/gui/src/components/aitoolkit/AIToolkitPage.js index 23e38213d6814e85dbfc81db1a82312e2c3e6870..274c68ea48800555412009beb48aa2cc542746b1 100644 --- a/gui/src/components/aitoolkit/AIToolkitPage.js +++ b/gui/src/components/aitoolkit/AIToolkitPage.js @@ -108,8 +108,6 @@ export default function AIToolkitPage() { } }, []) - console.log(sections) - return {` diff --git a/gui/src/components/api.js b/gui/src/components/api.js index 4b719ffeea587ff4baed3f95be91a8031e731870..bbf45f5db43bd6a6553785db5d301b204a383d23 100644 --- a/gui/src/components/api.js +++ b/gui/src/components/api.js @@ -75,7 +75,7 @@ class Upload { } uploadFile(file) { - const uploadFileWithProgress = async() => { + const uploadFileWithProgress = async () => { const authHeaders = await this.api.authHeaders() let uploadRequest = await UploadRequest( { @@ -626,6 +626,20 @@ class Api { .finally(this.onFinishLoading) } + async publishUploadToCentralNomad(uploadId) { + this.onStartLoading() + return this.swagger() + .then(client => client.apis.uploads.exec_upload_operation({ + upload_id: uploadId, + payload: { + operation: 'publish-to-central-nomad' + } + })) + .catch(handleApiError) + .then(response => response.body) + .finally(this.onFinishLoading) + } + async getSignatureToken() { this.onStartLoading() return this.swagger() diff --git a/gui/src/components/archive/ArchiveBrowser.js b/gui/src/components/archive/ArchiveBrowser.js index ff82b8692dddec4fa4ff3bc3816e5a5dd6b59d2e..688f971684bf71794fead30436dbec17eacd8e89 100644 --- a/gui/src/components/archive/ArchiveBrowser.js +++ b/gui/src/components/archive/ArchiveBrowser.js @@ -406,7 +406,7 @@ function Overview({section, def}) { }, [setMode]) // Structure visualization for section_system - if (def.name === 'section_system') { + if (def.name === 'System') { let url = window.location.href let name = 'section_system' let rootIndex = url.indexOf(name) + name.length @@ -467,7 +467,7 @@ function Overview({section, def}) { > // Band structure plot for section_k_band - } else if (def.name === 'section_k_band') { + } else if (def.name === 'KBand') { return <> {mode === 'bs' ? @@ -515,7 +515,7 @@ function Overview({section, def}) { // DOS plot for section_dos - } else if (def.name === 'section_dos') { + } else if (def.name === 'Dos') { return - {sectionDefs.filter(def => !def.extends_base_section).map(def => { + {sectionDefs.filter(def => !def.extends_base_section).sort(defCompare).map(def => { const key = `section_definitions@${def._qualifiedName}` return {def.name} @@ -214,7 +218,7 @@ export class PackagePrefixAdaptor extends MetainfoAdaptor { })} - {sectionDefs.filter(def => def.extends_base_section).map(def => { + {sectionDefs.filter(def => def.extends_base_section).sort(defCompare).map(def => { const key = `section_definitions@${def._qualifiedName}` return {def.name} @@ -222,7 +226,7 @@ export class PackagePrefixAdaptor extends MetainfoAdaptor { })} - {categoryDefs.map(def => { + {categoryDefs.sort(defCompare).map(def => { const key = `category_definitions@${def._qualifiedName}` return {def.name} @@ -323,8 +327,10 @@ function SectionDef({def}) { {def.sub_sections.filter(filter) .map(subSectionDef => { const key = subSectionDef.name + const categories = subSectionDef.categories?.map(c => resolveRef(c)) + const unused = categories?.find(c => c.name === 'Unused') return - + {subSectionDef.name} {subSectionDef.repeats &&  (repeats)} @@ -337,9 +343,11 @@ function SectionDef({def}) { {def.quantities.filter(filter) .map(quantityDef => { const key = quantityDef.name + const categories = quantityDef.categories?.map(c => resolveRef(c)) + const unused = categories?.find(c => c.name === 'Unused') return - + {quantityDef.name} @@ -408,16 +416,19 @@ function DefinitionDetails({def, ...props}) { const lane = useContext(laneContext) const isLast = !lane.next const [usage, setUsage] = useState(null) + const [showUsage, setShowUsage] = useState(false) useEffect(() => { - api.quantity_search({ - 'dft.quantities': [def.name], - size: 100, // make sure we get all codes - quantity: 'dft.code_name' - }).then(result => { - setUsage(result.quantity.values) - }) - }, [api, def.name, setUsage]) + if (showUsage) { + api.quantity_search({ + 'dft.quantities': [def.name], + size: 100, // make sure we get all codes + quantity: 'dft.code_name' + }).then(result => { + setUsage(result.quantity.values) + }) + } + }, [api, def.name, showUsage, setUsage]) return {def.categories && def.categories.length > 0 && @@ -435,7 +446,8 @@ function DefinitionDetails({def, ...props}) { } {isLast && def.m_def !== 'Category' && def.name !== 'EntryArchive' && !def.extends_base_section && - {!usage && loading ...} + {!showUsage && } + {showUsage && !usage && loading ...} {usage && Object.keys(usage).length > 0 && ( ({ diff --git a/gui/src/components/dft/DFTVisualizations.js b/gui/src/components/dft/DFTVisualizations.js index f7ed3733d51ec4f3d61f6837f982600c21daa814..991147800bbe360665b8240c15d4f4f5af93168d 100644 --- a/gui/src/components/dft/DFTVisualizations.js +++ b/gui/src/components/dft/DFTVisualizations.js @@ -21,7 +21,7 @@ import { Grid } from '@material-ui/core' import { makeStyles } from '@material-ui/core/styles' import QuantityHistogram from '../search/QuantityHistogram' import { searchContext } from '../search/SearchContext' -import { path, defsByName } from '../archive/metainfo' +import { path, defsByName, resolveRef } from '../archive/metainfo' import { nomadTheme } from '../../config' import Markdown from '../Markdown' @@ -172,10 +172,14 @@ const useMetainfoTooltipStyles = makeStyles(theme => ({ function MetaInfoTooltip({def, path}) { const classes = useMetainfoTooltipStyles() + let description = def.description + if (!description && def.sub_section) { + description = resolveRef(def.sub_section)?.description + } return
{`${def.description.slice(0, def.description.indexOf('.') || undefined)}. Click [here](/metainfo/${path}) for full the definition.`} + >{`${description?.slice(0, description.indexOf('.') || undefined)}. Click [here](/metainfo/${path}) for full the definition.`}
} diff --git a/gui/src/components/entry/RawFiles.js b/gui/src/components/entry/RawFiles.js index 9d41c49103232058994de90c9a5198b0c5c20af2..0f22e433a10051fcc842cef951b068ce0e605ebf 100644 --- a/gui/src/components/entry/RawFiles.js +++ b/gui/src/components/entry/RawFiles.js @@ -25,7 +25,7 @@ import Download from './Download' import ReloadIcon from '@material-ui/icons/Cached' import ViewIcon from '@material-ui/icons/Search' import InfiniteScroll from 'react-infinite-scroller' -import { ScrollContext } from '../App' +import { ScrollContext } from '../nav/Navigation' class RawFiles extends React.Component { static propTypes = { @@ -124,7 +124,6 @@ class RawFiles extends React.Component { if (files.length > 500) { raiseError('There are more than 500 files in this entry. We can only show the first 500.') } - console.log('###', files) this.setState({files: files, loading: false}) }).catch(error => { this.setState({files: null, loading: false}) @@ -305,7 +304,7 @@ class RawFiles extends React.Component { loadMore={this.handleLoadMore.bind(this)} hasMore={fileContents.hasMore} useWindow={false} - getScrollParent={() => scroll.scrollParentRef} + getScrollParent={() => scroll.scrollParentRef.current} >
                     {`${fileContents.contents}`}
diff --git a/gui/src/components/errors.js b/gui/src/components/errors.js
index 6c85e924acd1a25191606e6ceeaab02b3051d57a..8a6ea93a3370b64dc534b444f75fb5697652c81a 100644
--- a/gui/src/components/errors.js
+++ b/gui/src/components/errors.js
@@ -21,6 +21,13 @@ import { SnackbarContent, IconButton, Snackbar, withStyles } from '@material-ui/
 import ErrorIcon from '@material-ui/icons/Error'
 import CloseIcon from '@material-ui/icons/Close'
 
+export class VersionMismatch extends Error {
+  constructor(msg) {
+    super(msg)
+    this.name = 'VersionMismatch'
+  }
+}
+
 export const errorContext = React.createContext({
   errors: [],
   raiseError: () => { throw Error('Error context used incorrectly.') }
diff --git a/gui/src/components/nav/AppBar.js b/gui/src/components/nav/AppBar.js
new file mode 100644
index 0000000000000000000000000000000000000000..335fc225a6c0b3f69627c6c00104ef3862c1ebbb
--- /dev/null
+++ b/gui/src/components/nav/AppBar.js
@@ -0,0 +1,109 @@
+/*
+ * Copyright The NOMAD Authors.
+ *
+ * This file is part of NOMAD. See https://nomad-lab.eu for further info.
+ *
+ * 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.
+ */
+
+import React, { useCallback, useContext, useEffect, useState } from 'react'
+import { useLocation } from 'react-router-dom'
+import { Typography,
+  AppBar as MuiAppBar, Toolbar, Link, LinearProgress, makeStyles } from '@material-ui/core'
+import { allRoutes as routes } from './Routes'
+import LoginLogout from '../LoginLogout'
+import HelpDialog from '../Help'
+import MainMenu from './MainMenu'
+import { apiContext } from '../api'
+import { guiBase } from '../../config'
+
+function LoadingIndicator() {
+  const {api} = useContext(apiContext)
+  const [loading, setLoading] = useState(0)
+  const handleOnLoading = useCallback(loading => setLoading(loading), [setLoading])
+  useEffect(() => {
+    api.onLoading(handleOnLoading)
+    return () => api.removeOnLoading(handleOnLoading)
+  }, [api, handleOnLoading])
+
+  return loading ?  : ''
+}
+
+const useAppBarStyles = makeStyles(theme => ({
+  root: {
+    zIndex: theme.zIndex.drawer + 1,
+    backgroundColor: 'white'
+  },
+  title: {
+    marginLeft: theme.spacing(1),
+    flexGrow: 1,
+    display: 'flex',
+    alignItems: 'center',
+    alignContent: 'flex-start',
+    color: theme.palette.primary.main
+  },
+  toolbar: {
+    paddingRight: theme.spacing(3)
+  },
+  helpButton: {
+    marginLeft: theme.spacing(1)
+  },
+  logo: {
+    height: theme.spacing(7),
+    marginRight: theme.spacing(2)
+  },
+  actions: {
+    display: 'flex',
+    alignItems: 'center'
+  },
+  button: {
+    borderColor: theme.palette.getContrastText(theme.palette.primary.main),
+    marginRight: 0
+  },
+  mainMenu: {
+    marginLeft: theme.spacing(1)
+  }
+}))
+
+export default function AppBar() {
+  const classes = useAppBarStyles()
+  const {pathname} = useLocation()
+  const selectedRouteKey = Object.keys(routes).find(key => {
+    const route = routes[key]
+    return pathname.startsWith(route.path)
+  })
+  const selectedRoute = routes[selectedRouteKey]
+  const help = selectedRoute.appBarHelp
+  const title = selectedRoute.appBarTitle
+
+  return 
+    
+      
+ + The NOMAD logo + + + {title} + + {help ? : ''} +
+
+ +
+
+
+ +
+ +
+} diff --git a/gui/src/components/nav/MainMenu.js b/gui/src/components/nav/MainMenu.js new file mode 100644 index 0000000000000000000000000000000000000000..438e01e8923dce0aaf29c2919e2efd4f1f2459ff --- /dev/null +++ b/gui/src/components/nav/MainMenu.js @@ -0,0 +1,208 @@ +/* + * Copyright The NOMAD Authors. + * + * This file is part of NOMAD. See https://nomad-lab.eu for further info. + * + * 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. + */ + +import { Button, Dialog, DialogActions, DialogContent, DialogTitle, FormControlLabel, + FormGroup, + Switch} from '@material-ui/core' +import React, { useEffect, useMemo, useRef, useState } from 'react' +import { useLocation } from 'react-router-dom' +import Markdown from '../Markdown' +import { allRoutes as routes } from './Routes' +import { matomo } from '../App' +import { useCookies } from 'react-cookie' +import { MenuBar, MenuBarItem, MenuBarMenu } from './MenuBar' +import { guiBase, consent, appBase, oasis, aitoolkitEnabled, encyclopediaEnabled } from '../../config' + +import BackupIcon from '@material-ui/icons/Backup' +import SearchIcon from '@material-ui/icons/Search' +import UserDataIcon from '@material-ui/icons/AccountCircle' +import AboutIcon from '@material-ui/icons/Home' +import ForumIcon from '@material-ui/icons/QuestionAnswer' +import FAQIcon from '@material-ui/icons/LiveHelp' +import EncyclopediaIcon from '@material-ui/icons/Language' +import MetainfoIcon from '@material-ui/icons/Info' +import DocIcon from '@material-ui/icons/Help' +import CodeIcon from '@material-ui/icons/Code' +import TermsIcon from '@material-ui/icons/Assignment' +import AnalyticsIcon from '@material-ui/icons/ShowChart' + +function Consent(moreProps) { + const [cookies, setCookie] = useCookies() + const [accepted, setAccepted] = useState(cookies['terms-accepted']) + const [optOut, setOptOut] = useState(cookies['tracking-enabled'] === 'false') + const cookieOptions = useMemo(() => ({ + expires: new Date(2147483647 * 1000), + path: '/' + guiBase.split('/').slice(1).join('/') + }), []) + + useEffect(() => { + if (!optOut) { + matomo.push(['setConsentGiven']) + } else { + matomo.push(['requireConsent']) + } + }) + + // Write again to push forwards Safari's hard-coded 7 days ITP window + useEffect(() => { + setCookie('terms-accepted', cookies['terms-accepted'], cookieOptions) + setCookie('tracking-enabled', cookies['tracking-enabled'], cookieOptions) + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + []) + + const handleClosed = accepted => { + if (accepted) { + setCookie('terms-accepted', true, cookieOptions) + setCookie('tracking-enabled', !optOut, cookieOptions) + setAccepted(true) + } + } + const handleOpen = () => { + setCookie('terms-accepted', false, cookieOptions) + setAccepted(false) + } + + return ( + + } + {...moreProps} + /> + + Terms of Use + + {consent} + + { + setOptOut(!optOut) + }} + color="primary" + />} + label="Do not provide information about your use of NOMAD (opt-out)." + /> + + + + + + + + ) +} + +export default function MainMenu() { + // We keep the URL of those path where components keep meaningful state in the URL. + // If the menu is used to comeback, the old URL is used. Therefore, it appears as + // if the same component instance with the same state is still there. + const {pathname, search} = useLocation() + const historyRef = useRef({ + search: '/search', + userdata: '/userdata' + }) + const history = {...historyRef.current} + Object.keys(historyRef.current).forEach(key => { + if (pathname.startsWith('/' + key)) { + historyRef.current[key] = pathname + (search || '') + history[key] = '/' + key + } + }) + const route = Object.keys(routes).find(routeKey => pathname.startsWith(routes[routeKey].path)) + const routeNavPath = route && routes[route].navPath + if (routeNavPath) { + historyRef.current.navPath = routeNavPath + } + const selected = (route && routes[route].navPath) || historyRef.current.navPath || (route && routes[route].defaultNavPath) || 'publish/uploads' + + return + }> + } + /> + } + /> + + }> + + {encyclopediaEnabled && } + />} + + }> + {!oasis && aitoolkitEnabled && } + />} + + + }> + + } + /> + } + /> + } + /> + } + /> + + + +} diff --git a/gui/src/components/nav/MainMenu.spec.js b/gui/src/components/nav/MainMenu.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..bc4f8de3f7a08cda12fee3917858491929439371 --- /dev/null +++ b/gui/src/components/nav/MainMenu.spec.js @@ -0,0 +1,48 @@ +/* + * Copyright The NOMAD Authors. + * + * This file is part of NOMAD. See https://nomad-lab.eu for further info. + * + * 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. + */ + +// import React from 'react' +import 'regenerator-runtime/runtime' +// import { toBeInTheDocument } from '@testing-library/jest-dom' +// import { render, screen, within } from '@testing-library/react' +// import { MemoryRouter } from 'react-router-dom' +// import MainMenu from './MainMenu' +// import { allRoutes as routes } from './Routes' + +// expect.extend({ toBeInTheDocument }) + +describe('', () => { + it('renders menu items for all nav paths', () => { + // render( + // + // ) + // Object.keys(routes).forEach(key => { + // const route = routes[key] + // if (route.navPath) { + // let item = screen + // const path = route.navPath.split('/') + // for (let i = 0; i < path.length; i++) { + // const itemId = path[i] + // const element = item.getByTestId(itemId) + // expect(element).toBeInTheDocument() + // item = within(element) + // } + // } + // }) + }) +}) diff --git a/gui/src/components/nav/MenuBar.js b/gui/src/components/nav/MenuBar.js new file mode 100644 index 0000000000000000000000000000000000000000..3412d395592bfd122f28d4ff3dd480a354277bc2 --- /dev/null +++ b/gui/src/components/nav/MenuBar.js @@ -0,0 +1,210 @@ +/* + * Copyright The NOMAD Authors. + * + * This file is part of NOMAD. See https://nomad-lab.eu for further info. + * + * 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. + */ + +import React, { useContext, useState } from 'react' +import PropTypes from 'prop-types' +import { Button, makeStyles, MenuItem as MuiMenuItem, Menu as MuiMenu, ClickAwayListener, ListItemText } from '@material-ui/core' +import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown' +import { useHistory } from 'react-router-dom' + +const capitalize = (s) => { + if (typeof s !== 'string') return '' + return s.charAt(0).toUpperCase() + s.slice(1) +} + +const MenuBarContext = React.createContext({}) + +const useMenuBarStyles = makeStyles(theme => ({ + root: { + margin: theme.spacing(1), + width: '100%', + display: 'flex', + flexDirection: 'row', + flexWrap: 'nowrap', + justifyContent: 'left' + } +})) + +export function MenuBar({children, selected}) { + const classes = useMenuBarStyles() + + const [openMenu, setOpenMenu] = useState(null) + const [openMenuAnchorEl, setOpenMenuAnchorEl] = useState(null) + + const handleClickMenu = (menuName, event) => { + setOpenMenu(menuName) + setOpenMenuAnchorEl(event.currentTarget) + } + + const handleCloseMenus = () => { + setOpenMenu(null) + setOpenMenuAnchorEl(null) + } + + const [selectedMenu, selectedMenuItem] = (selected || '').split('/') + + const context = { + selectedMenu: selectedMenu, + selectedMenuItem: selectedMenuItem, + openMenu: openMenu, + openMenuAnchorEl: openMenuAnchorEl, + onClickMenu: handleClickMenu, + onCloseMenu: handleCloseMenus + } + return +
+ {children} +
+
+} +MenuBar.propTypes = { + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node + ]), + selected: PropTypes.string.isRequired +} + +const useMenuBarItemStyles = makeStyles(theme => ({ + selected: { + color: theme.palette.primary.main + }, + link: { + color: 'inherit', + textDecoration: 'none' + } +})) + +export const MenuBarItem = React.forwardRef(({name, label, tooltip, route, href, onClick}, ref) => { + const classes = useMenuBarItemStyles() + + label = label || capitalize(name) + const context = useContext(MenuBarContext) + const selected = context.selectedMenuItem === name + + const history = useHistory() + + const handleClick = () => { + context.onCloseMenu(context.selectedMenu) + if (route) { + history.push(route) + } else if (!href) { + onClick() + } + } + + const item = + + + + return href ? {item} : item +}) +MenuBarItem.propTypes = { + name: PropTypes.string.isRequired, + label: PropTypes.string, + tooltip: PropTypes.string, + icon: PropTypes.node, + route: PropTypes.string, + href: PropTypes.string, + onClick: PropTypes.func +} + +const useMenuBarMenuStyles = makeStyles(theme => ({ + root: { + marginLeft: theme.spacing(1), + '&:first-child': { + marginLeft: theme.spacing(0) + } + }, + menuPopover: { + pointerEvents: 'none' + }, + menuPaper: { + pointerEvents: 'all' + } +})) + +export function MenuBarMenu({name, label, children}) { + const classes = useMenuBarMenuStyles() + label = label || capitalize(name) + const context = useContext(MenuBarContext) + + const selected = context.selectedMenu === name + const open = context.openMenu === name + const aMenuIsOpen = context.openMenu !== null + const anchorEl = open ? context.openMenuAnchorEl : undefined + + const handleClick = (event) => { + context.onClickMenu(name, event) + } + + const handleMouseOver = (event) => { + if (aMenuIsOpen) { + context.onClickMenu(name, event) + } + } + + const handleClose = () => { + if (open) { + context.onCloseMenu(name) + } + } + + return + + + + + {children} + + +} +MenuBarMenu.propTypes = { + name: PropTypes.string.isRequired, + label: PropTypes.string, + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node + ]) +} diff --git a/gui/src/components/nav/MenuBar.spec.js b/gui/src/components/nav/MenuBar.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..6712a7a6703244f543cdadb60e9d99fe01152ed6 --- /dev/null +++ b/gui/src/components/nav/MenuBar.spec.js @@ -0,0 +1,118 @@ +/* + * Copyright The NOMAD Authors. + * + * This file is part of NOMAD. See https://nomad-lab.eu for further info. + * + * 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. + */ + +import React from 'react' +import 'regenerator-runtime/runtime' +import { toHaveStyle, toBeVisible } from '@testing-library/jest-dom' +import { render, screen, fireEvent, waitFor } from '@testing-library/react' +import { MenuBar, MenuBarItem, MenuBarMenu } from './MenuBar' +import { MemoryRouter } from 'react-router-dom' + +function toBePrimaryColored(htmlElement) { + return toHaveStyle(htmlElement, 'color: rgb(63, 81, 181)') +} + +expect.extend({ toHaveStyle, toBeVisible, toBePrimaryColored }) + +describe('', () => { + const createExampleMenu = () => + + + + + + + + + + +
+ + + it('renders', () => { + render(createExampleMenu()) + expect(screen.getAllByRole('button').length).toBe(2) + expect(screen.getByText('Foo-one')).not.toBeVisible() + expect(screen.getByText('Bar-one')).not.toBeVisible() + }) + + it('highlights selected', () => { + render(createExampleMenu()) + expect(screen.getByText('Foo').parentElement).toBePrimaryColored() + expect(screen.getByText('Foo-two').parentElement.parentElement).toBePrimaryColored() + expect(screen.getByText('Foo-one').parentElement.parentElement).not.toBePrimaryColored() + expect(screen.getByText('Bar').parentElement).not.toBePrimaryColored() + }) + + it('opens menu on button click', async () => { + render(createExampleMenu()) + + expect(screen.getAllByRole('button').length).toBe(2) + expect(screen.getByText('Foo-one')).not.toBeVisible() + expect(screen.getByText('Bar-one')).not.toBeVisible() + fireEvent.click(screen.getByText('Foo')) + await waitFor(() => + expect(screen.getByRole('menu')).toBeVisible() + ) + + expect(screen.getByText('Foo-one')).toBeVisible() + expect(screen.getByText('Bar-one')).not.toBeVisible() + }) + + it('changes open menu on hover', async () => { + render(createExampleMenu()) + + fireEvent.click(screen.getByText('Foo')) + await waitFor(() => + expect(screen.getByRole('menu')).toBeVisible() + ) + fireEvent.mouseOver(screen.getByText('Bar')) + await waitFor(() => + expect(screen.getByRole('menu')).toBeVisible() + ) + + expect(screen.getByText('Foo-one')).not.toBeVisible() + expect(screen.getByText('Bar-one')).toBeVisible() + }) + + it('closes menu on item click', async () => { + render(createExampleMenu()) + + fireEvent.click(screen.getByText('Foo')) + await waitFor(() => + expect(screen.getByRole('menu')).toBeVisible() + ) + fireEvent.click(screen.getByText('Foo-one')) + await waitFor(() => + expect(screen.getByText('Foo-one')).not.toBeVisible() + ) + }) + + it('closes menu on click somewhere', async () => { + render(createExampleMenu()) + + fireEvent.click(screen.getByText('Foo')) + await waitFor(() => + expect(screen.getByRole('menu')).toBeVisible() + ) + fireEvent.click(screen.getByTestId('content')) + await waitFor(() => + expect(screen.getByText('Foo-one')).not.toBeVisible() + ) + }) +}) diff --git a/gui/src/components/nav/Navigation.js b/gui/src/components/nav/Navigation.js new file mode 100644 index 0000000000000000000000000000000000000000..8cc24f4ffdc7f2eec25e2bbebf9c169d62c52e77 --- /dev/null +++ b/gui/src/components/nav/Navigation.js @@ -0,0 +1,152 @@ +/* + * Copyright The NOMAD Authors. + * + * This file is part of NOMAD. See https://nomad-lab.eu for further info. + * + * 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. + */ + +import React, { useEffect, useRef, useState } from 'react' +import { makeStyles } from '@material-ui/core/styles' +import { Snackbar, SnackbarContent, IconButton, Link as MuiLink } from '@material-ui/core' +import UnderstoodIcon from '@material-ui/icons/Check' +import { amber } from '@material-ui/core/colors' +import AppBar from './AppBar' +import { guiBase, version } from '../../config' +import packageJson from '../../../package.json' +import Routes from './Routes' +import { withApi } from '../api' + +export const ScrollContext = React.createContext({scrollParentRef: null}) + +function ReloadSnack() { + return + There is a new NOMAD version. Please press your browser's reload (or even shift+reload) button.} + /> + +} + +const useBetaSnackStyles = makeStyles(theme => ({ + root: {}, + snack: { + backgroundColor: amber[700] + } +})) +function BetaSnack() { + const classes = useBetaSnackStyles() + const [understood, setUnderstood] = useState(false) + + if (!version) { + console.warn('no version data available') + return '' + } + + if (!version.isBeta && !version.isTest) { + return '' + } + + return + + You are using a {version.isBeta ? 'beta' : 'test'} version of NOMAD ({version.label}). { + version.usesBetaData ? 'This version is not using the official data. Everything you upload here, might get lost.' : '' + } Click here for the official NOMAD version. + } + action={[ + setUnderstood(true)}> + + + ]} + /> + +} + +const useStyles = makeStyles(theme => ({ + root: { + minWidth: 1024 + }, + appFrame: { + zIndex: 1, + overflow: 'hidden', + position: 'relative', + display: 'flex', + width: '100%', + height: '100vh' + }, + content: { + marginTop: theme.spacing(14), + flexGrow: 1, + backgroundColor: theme.palette.background.default, + width: '100%', + overflow: 'auto' + } +})) + +function Navigation() { + const classes = useStyles() + const [showReloadSnack, setShowReloadSnack] = useState(false) + const scrollParentRef = useRef(null) + + useEffect(() => { + fetch(`${guiBase}/meta.json`, { + method: 'GET', + cache: 'no-cache', + headers: { + 'Pragma': 'no-cache', + 'Cache-Control': 'no-cache, no-store' + } + }).then((response) => response.json()) + .then((meta) => { + if (meta.commit !== packageJson.commit) { + console.log('GUI API version mismatch') + setShowReloadSnack(true) + } + }) + .catch(() => { + console.log('Could not validate version, continue...') + }) + }, [setShowReloadSnack]) + + return ( +
+
+ { showReloadSnack ? : ''} + + + +
+ + + +
+
+
+ ) +} + +export default withApi(false)(Navigation) diff --git a/gui/src/components/nav/Routes.js b/gui/src/components/nav/Routes.js new file mode 100644 index 0000000000000000000000000000000000000000..22b5650067c34854a92aec413702eeea735f0907 --- /dev/null +++ b/gui/src/components/nav/Routes.js @@ -0,0 +1,162 @@ +/* + * Copyright The NOMAD Authors. + * + * This file is part of NOMAD. See https://nomad-lab.eu for further info. + * + * 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. + */ + +import React from 'react' +import { Route } from 'react-router-dom' +import About from '../About' +import AIToolkitPage from '../aitoolkit/AIToolkitPage' +import { MetainfoPage, help as metainfoHelp } from '../archive/MetainfoBrowser' +import ResolveDOI from '../dataset/ResolveDOI' +import DatasetPage from '../DatasetPage' +import EntryPage, {help as entryHelp} from '../entry/EntryPage' +import EntryQuery from '../entry/EntryQuery' +import ResolvePID from '../entry/ResolvePID' +import FAQ from '../FAQ' +import SearchPage, {help as searchHelp} from '../search/SearchPage' +import UploadPage, {help as uploadHelp} from '../uploads/UploadPage' +import UserdataPage, {help as userdataHelp} from '../UserdataPage' + +export const routes = { + 'faq': { + path: '/faq', + exact: true, + appBarTitle: 'Frequently Asked Questions', + component: FAQ + }, + 'search': { + path: '/search', + exact: true, + appBarTitle: 'Find and Download Data', + appBarHelp: { + title: 'How to find and download data', + content: searchHelp + }, + navPath: 'explore/search', + component: SearchPage + }, + 'userdata': { + path: '/userdata', + exact: true, + appBarTitle: 'Manage Your Data', + appBarHelp: { + title: 'How to manage your data', + content: userdataHelp + }, + navPath: 'publish/userdata', + component: UserdataPage + }, + 'entry': { + path: '/entry', + appBarTitle: 'Entry', + appBarHelp: { + title: 'The entry page', + content: entryHelp + }, + defaultNavPath: 'explore/search', + routes: [ + { + path: '/id', + component: EntryPage + }, + { + path: '/query', + exact: true, + component: EntryQuery + }, + { + path: '/pid', + component: ResolvePID + } + ] + }, + 'dataset': { + path: '/dataset', + appBarTitle: 'Dataset', + defaultNavPath: 'explore/search', + routes: [ + { + path: '/id', + component: DatasetPage + }, + { + path: '/doi', + component: ResolveDOI + } + ] + }, + 'uploads': { + path: '/uploads', + exact: true, + appBarTitle: 'Upload and Publish Data', + appBarHelp: { + title: 'How to upload data', + content: uploadHelp + }, + navPath: 'publish/uploads', + component: UploadPage + }, + 'metainfo': { + path: '/metainfo', + appBarTitle: 'The NOMAD Meta Info', + appBarHelp: { + title: 'About the NOMAD meta-info', + content: metainfoHelp + }, + navPath: 'analyze/metainfo', + component: MetainfoPage + }, + 'aitoolkit': { + path: '/aitoolkit', + appBarTitle: 'Artificial Intelligence Toolkit', + navPath: 'analyze/aitoolkit', + component: AIToolkitPage + }, + 'about': { + exact: true, + path: '/', + appBarTitle: 'About, Documentation, Getting Help', + navPath: 'about/info', + component: About + } +} + +export const allRoutes = Object.keys(routes).map(key => { + const route = routes[key] + return route.routes + ? route.routes.map(subRoute => ({ + ...route, + ...subRoute, + path: `${route.path}/${subRoute.path.replace(/^\/+/, '')}`, + routes: undefined + })) + : route +}).flat() + +export default function Routes() { + return + {Object.keys(allRoutes).map(routeKey => { + const route = allRoutes[routeKey] + const { path, exact } = route + const children = childProps => childProps.match && + return + })} + +} diff --git a/gui/src/components/test.js b/gui/src/components/test.js deleted file mode 100644 index e433056ead52c01cd689854d3df6619fe7400235..0000000000000000000000000000000000000000 --- a/gui/src/components/test.js +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright The NOMAD Authors. - * - * This file is part of NOMAD. See https://nomad-lab.eu for further info. - * - * 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. - */ -import React from 'react' - -export default function Example(props) { - return - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - repository - - - 63TB raw data - 10 million code runs - - - 109 million - calculation results - 800 million - quantities - - - processing - - - upload - - - explore - - - API - - - archive - - - encyclopedia - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -} diff --git a/gui/src/components/uploads/Upload.js b/gui/src/components/uploads/Upload.js index 5df31bb9fe38ab7a26740f3d56f664fbae525ec9..93e4b5c3645ef8cced316b18b2dd4758b22e48db 100644 --- a/gui/src/components/uploads/Upload.js +++ b/gui/src/components/uploads/Upload.js @@ -26,7 +26,7 @@ import ReactJson from 'react-json-view' import { compose } from 'recompose' import { withErrors } from '../errors' import { withRouter } from 'react-router' -import { debug } from '../../config' +import { debug, oasis } from '../../config' import EntryList, { EntryListUnstyled } from '../search/EntryList' import DeleteIcon from '@material-ui/icons/Delete' import PublishIcon from '@material-ui/icons/Publish' @@ -116,6 +116,47 @@ class PublishConfirmDialog extends React.Component { } } +class PublishToCentralNomadConfirmDialog extends React.Component { + static propTypes = { + onPublish: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + open: PropTypes.bool.isRequired + } + + state = { + embargoLength: 0 + } + + render() { + const { onPublish, onClose, open } = this.props + return ( +
+ + Publish data to central NOMAD + + {` + If you agree this upload will be published from this OASIS to the + central NOMAD. Only the data without an embargo will be published. + This operation cannot be repeated. + `} + + + + + + +
+ ) + } +} + class Upload extends React.Component { static propTypes = { classes: PropTypes.object.isRequired, @@ -203,6 +244,7 @@ class Upload extends React.Component { }, updating: true, // it is still not complete and continuously looking for updates showPublishDialog: false, + showPublishToCentralNomadDialog: false, showDeleteDialog: false, columns: {}, expanded: null @@ -219,6 +261,9 @@ class Upload extends React.Component { this.handlePublishCancel = this.handlePublishCancel.bind(this) this.handlePublishOpen = this.handlePublishOpen.bind(this) this.handlePublishSubmit = this.handlePublishSubmit.bind(this) + this.handlePublishToCentralNomadSubmit = this.handlePublishToCentralNomadSubmit.bind(this) + this.handlePublishToCentralNomadCancel = this.handlePublishToCentralNomadCancel.bind(this) + this.handlePublishToCentralNomadOpen = this.handlePublishToCentralNomadOpen.bind(this) } componentDidUpdate(prevProps, prevState) { @@ -369,6 +414,10 @@ class Upload extends React.Component { this.setState({showPublishDialog: true}) } + handlePublishToCentralNomadOpen() { + this.setState({showPublishToCentralNomadDialog: true}) + } + handlePublishSubmit(embargoLength) { const { api, upload } = this.props api.publishUpload(upload.upload_id, embargoLength) @@ -383,6 +432,24 @@ class Upload extends React.Component { }) } + handlePublishToCentralNomadSubmit() { + const { api, upload } = this.props + api.publishUploadToCentralNomad(upload.upload_id) + .then(() => { + this.setState({showPublishToCentralNomadDialog: false}) + this.update() + }) + .catch(error => { + this.props.raiseError(error) + this.setState({showPublishToCentralNomadDialog: false}) + this.update() + }) + } + + handlePublishToCentralNomadCancel() { + this.setState({showPublishToCentralNomadDialog: false}) + } + handlePublishCancel() { this.setState({showPublishDialog: false}) } @@ -605,19 +672,31 @@ class Upload extends React.Component { } const running = upload.tasks_running || upload.process_running + const alreadyPublishedToCentralNomad = upload.published_to && upload.published_to.length > 0 - const actions = upload.published ? : - - - - - - - - - - - + const actions = upload.published + ? + {oasis && + + + + } + + : + + + + + + + + + + + return : '' } + {last_status_message && + {last_status_message} + } {this.renderCalcTable()} {debug ?
@@ -696,6 +778,11 @@ class Upload extends React.Component { onClose={this.handlePublishCancel} onPublish={this.handlePublishSubmit} /> + }> - - - - - - , document.getElementById('root')) +ReactDOM.render(, document.getElementById('root')) // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. diff --git a/gui/src/setupTests.js b/gui/src/setupTests.js new file mode 100644 index 0000000000000000000000000000000000000000..3c6e9ff29c5f322e5a3fc2c606e2955189f71e75 --- /dev/null +++ b/gui/src/setupTests.js @@ -0,0 +1,20 @@ +global.nomadEnv = { + 'keycloakBase': 'https://nomad-lab.eu/fairdi/keycloak/auth/', + 'keycloakRealm': 'fairdi_nomad_test', + 'keycloakClientId': 'nomad_gui_dev', + 'appBase': 'http://nomad-lab.eu/prod/rae/beta', + 'debug': false, + 'matomoEnabled': false, + 'matomoUrl': 'https://nomad-lab.eu/fairdi/stat', + 'matomoSiteId': '2', + 'version': { + 'label': '0.9.8', + 'isBeta': false, + 'isTest': true, + 'usesBetaData': true, + 'officialUrl': 'https://nomad-lab.eu/prod/rae/gui' + }, + 'encyclopediaEnabled': true, + 'aitoolkitEnabled': true, + 'oasis': false +} diff --git a/gui/yarn.lock b/gui/yarn.lock index a1c252a2ad373a7f4a253fe37d623ced4f7ec312..4c0ebe4fb7f9dcbc16e44a7be21ead070d2751c5 100644 --- a/gui/yarn.lock +++ b/gui/yarn.lock @@ -9,6 +9,13 @@ dependencies: "@babel/highlight" "^7.8.3" +"@babel/code-frame@^7.10.4": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + "@babel/compat-data@^7.9.0", "@babel/compat-data@^7.9.6": version "7.9.6" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.9.6.tgz#3f604c40e420131affe6f2c8052e9a275ae2049b" @@ -258,6 +265,11 @@ dependencies: "@babel/types" "^7.8.3" +"@babel/helper-validator-identifier@^7.10.4": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + "@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5": version "7.9.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" @@ -282,6 +294,15 @@ "@babel/traverse" "^7.9.6" "@babel/types" "^7.9.6" +"@babel/highlight@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/highlight@^7.8.3": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" @@ -1000,7 +1021,15 @@ core-js "^2.6.5" regenerator-runtime "^0.13.4" -"@babel/runtime-corejs3@^7.7.4", "@babel/runtime-corejs3@^7.8.3": +"@babel/runtime-corejs3@^7.10.2": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.12.5.tgz#ffee91da0eb4c6dae080774e94ba606368e414f4" + integrity sha512-roGr54CsTmNPPzZoCP1AmDXuBoNao7tnSA83TXTwt+UK5QVyh1DIJnrgYRPWKCF2flqZQXwa7Yr8v7VmLzF0YQ== + dependencies: + core-js-pure "^3.0.0" + regenerator-runtime "^0.13.4" + +"@babel/runtime-corejs3@^7.8.3": version "7.9.6" resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.9.6.tgz#67aded13fffbbc2cb93247388cf84d77a4be9a71" integrity sha512-6toWAfaALQjt3KMZQc6fABqZwUDDuWzz+cAfPhqyEnzxvdWOAkjwPNxgF8xlmo7OWLsSjaKjsskpKHRLaMArOA== @@ -1029,13 +1058,20 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.9.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f" integrity sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ== dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" + integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.4.0", "@babel/template@^7.8.3", "@babel/template@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" @@ -1186,6 +1222,17 @@ jest-message-util "^24.9.0" jest-mock "^24.9.0" +"@jest/fake-timers@^25.1.0": + version "25.5.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.5.0.tgz#46352e00533c024c90c2bc2ad9f2959f7f114185" + integrity sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ== + dependencies: + "@jest/types" "^25.5.0" + jest-message-util "^25.5.0" + jest-mock "^25.5.0" + jest-util "^25.5.0" + lolex "^5.0.0" + "@jest/reporters@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" @@ -1282,15 +1329,26 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + "@kyleshockey/object-assign-deep@^0.4.0": version "0.4.2" resolved "https://registry.yarnpkg.com/@kyleshockey/object-assign-deep/-/object-assign-deep-0.4.2.tgz#84900f0eefc372798f4751b5262830b8208922ec" integrity sha1-hJAPDu/DcnmPR1G1JigwuCCJIuw= -"@lauri-codes/materia@0.0.9": - version "0.0.9" - resolved "https://registry.yarnpkg.com/@lauri-codes/materia/-/materia-0.0.9.tgz#3ac8cac1b9ce8201a9e881afc0c5c6652c5a692a" - integrity sha512-qtY3pOWCKVG6z6iEs88vl/hqQNgK3tSCVNcAkSKFnuhk/Qdk66xHl7ZGVDMAOyqdXukNR2+iuZC/6CdFKc6/ow== +"@lauri-codes/materia@0.0.10": + version "0.0.10" + resolved "https://registry.yarnpkg.com/@lauri-codes/materia/-/materia-0.0.10.tgz#d9e1651a3ea9114f06493e3fe89e67f6e676e1b0" + integrity sha512-8CquRepcaIkRXZ5SmXP4kxd0vQ7ORWHBJSWKzUZyhbQa4rLmGwVyahZaDxFUy/9bFaJ3JMprAOYDkRx6cYrnwQ== dependencies: three "^0.119.1" threejs-meshline "^2.0.11" @@ -1410,15 +1468,38 @@ resolved "https://registry.yarnpkg.com/@navjobs/upload/-/upload-3.2.0.tgz#3802182fa7ec2212d94895d2b4c6a11058ec5600" integrity sha512-29vYAq/KjpSNRLgQlHVsCm4BAMcpebJ1g5/f9NOd/1a5nyWBsUhGT37GTex7siUnxGwKDF5c4l7nsjvOeGuu3g== +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + "@nodelib/fs.stat@^1.1.2": version "1.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== -"@sheerun/mutationobserver-shim@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25" - integrity sha512-DetpxZw1fzPD5xUBrIAoplLChO2VB8DlL5Gg+I1IR9b2wPqYIca2WSUxL5g1vLeR4MsQq1NeWriXAVffV+U1Fw== +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + +"@sinonjs/commons@^1.7.0": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217" + integrity sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw== + dependencies: + type-detect "4.0.8" "@svgr/babel-plugin-add-jsx-attribute@^4.2.0": version "4.2.0" @@ -1523,18 +1604,19 @@ "@svgr/plugin-svgo" "^4.3.1" loader-utils "^1.2.3" -"@testing-library/dom@^6.15.0": - version "6.16.0" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-6.16.0.tgz#04ada27ed74ad4c0f0d984a1245bb29b1fd90ba9" - integrity sha512-lBD88ssxqEfz0wFL6MeUyyWZfV/2cjEZZV3YRpb2IoJRej/4f1jB0TzqIOznTpfR1r34CNesrubxwIlAQ8zgPA== +"@testing-library/dom@^7.22.3": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.29.0.tgz#60b18065bab50a5cde21fe80275a47a43024d9cc" + integrity sha512-0hhuJSmw/zLc6ewR9cVm84TehuTd7tbqBX9pRNSp8znJ9gTmSgesdbiGZtt8R6dL+2rgaPFp9Yjr7IU1HWm49w== dependencies: - "@babel/runtime" "^7.8.4" - "@sheerun/mutationobserver-shim" "^0.3.2" - "@types/testing-library__dom" "^6.12.1" - aria-query "^4.0.2" - dom-accessibility-api "^0.3.0" - pretty-format "^25.1.0" - wait-for-expect "^3.0.2" + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^4.2.0" + aria-query "^4.2.2" + chalk "^4.1.0" + dom-accessibility-api "^0.5.4" + lz-string "^1.4.4" + pretty-format "^26.6.2" "@testing-library/jest-dom@^4.2.4": version "4.2.4" @@ -1551,24 +1633,28 @@ pretty-format "^24.0.0" redent "^3.0.0" -"@testing-library/react@^9.3.2": - version "9.5.0" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-9.5.0.tgz#71531655a7890b61e77a1b39452fbedf0472ca5e" - integrity sha512-di1b+D0p+rfeboHO5W7gTVeZDIK5+maEgstrZbWZSSvxDyfDRkkyBE1AJR5Psd6doNldluXlCWqXriUfqu/9Qg== +"@testing-library/react@^10.0.0": + version "10.4.9" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-10.4.9.tgz#9faa29c6a1a217bf8bbb96a28bd29d7a847ca150" + integrity sha512-pHZKkqUy0tmiD81afs8xfiuseXfU/N7rAX3iKjeZYje86t9VaB0LrxYVa+OOsvkrveX5jCK3IjajVn2MbePvqA== dependencies: - "@babel/runtime" "^7.8.4" - "@testing-library/dom" "^6.15.0" - "@types/testing-library__react" "^9.1.2" + "@babel/runtime" "^7.10.3" + "@testing-library/dom" "^7.22.3" "@testing-library/user-event@^7.1.2": version "7.2.1" resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-7.2.1.tgz#2ad4e844175a3738cb9e7064be5ea070b8863a1c" integrity sha512-oZ0Ib5I4Z2pUEcoo95cT1cr6slco9WY7yiPpG+RGNkj8YcYgJnM7pXmYmorNOReh8MIGcKSqXyeGjxnr8YiZbA== +"@types/aria-query@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" + integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A== + "@types/babel__core@^7.1.0": - version "7.1.7" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.7.tgz#1dacad8840364a57c98d0dd4855c6dd3752c6b89" - integrity sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw== + version "7.1.12" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.12.tgz#4d8e9e51eb265552a7e4f1ff2219ab6133bdfb2d" + integrity sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -1655,6 +1741,13 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" +"@types/istanbul-reports@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" + integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== + dependencies: + "@types/istanbul-lib-report" "*" + "@types/json-schema@^7.0.3": version "7.0.4" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" @@ -1690,13 +1783,6 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== -"@types/react-dom@*": - version "16.9.7" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.7.tgz#60844d48ce252d7b2dccf0c7bb937130e27c0cd2" - integrity sha512-GHTYhM8/OwUCf254WO5xqR/aqD3gC9kSTLpopWGpQLpnw23jk44RvMHsyUSEplvRJZdHxhJGMMLF0kCPYHPhQA== - dependencies: - "@types/react" "*" - "@types/react-transition-group@^4.2.0": version "4.2.4" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.2.4.tgz#c7416225987ccdb719262766c1483da8f826838d" @@ -1717,29 +1803,6 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== -"@types/testing-library__dom@*": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@types/testing-library__dom/-/testing-library__dom-7.0.2.tgz#2906f8a0dce58b0746c6ab606f786bd06fe6940e" - integrity sha512-8yu1gSwUEAwzg2OlPNbGq+ixhmSviGurBu1+ivxRKq1eRcwdjkmlwtPvr9VhuxTq2fNHBWN2po6Iem3Xt5A6rg== - dependencies: - pretty-format "^25.1.0" - -"@types/testing-library__dom@^6.12.1": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@types/testing-library__dom/-/testing-library__dom-6.14.0.tgz#1aede831cb4ed4a398448df5a2c54b54a365644e" - integrity sha512-sMl7OSv0AvMOqn1UJ6j1unPMIHRXen0Ita1ujnMX912rrOcawe4f7wu0Zt9GIQhBhJvH2BaibqFgQ3lP+Pj2hA== - dependencies: - pretty-format "^24.3.0" - -"@types/testing-library__react@^9.1.2": - version "9.1.3" - resolved "https://registry.yarnpkg.com/@types/testing-library__react/-/testing-library__react-9.1.3.tgz#35eca61cc6ea923543796f16034882a1603d7302" - integrity sha512-iCdNPKU3IsYwRK9JieSYAiX0+aYDXOGAmrC/3/M7AqqSDKnWWVv07X+Zk1uFSL7cMTUYzv4lQRfohucEocn5/w== - dependencies: - "@types/react-dom" "*" - "@types/testing-library__dom" "*" - pretty-format "^25.1.0" - "@types/unist@^2.0.0", "@types/unist@^2.0.2": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" @@ -1784,6 +1847,29 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" +"@typescript-eslint/experimental-utils@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz#e179ffc81a80ebcae2ea04e0332f8b251345a686" + integrity sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/types" "3.10.1" + "@typescript-eslint/typescript-estree" "3.10.1" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/experimental-utils@^4.0.1": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.10.0.tgz#dbf5d0f89802d5feaf7d11e5b32df29bbc2f3a0e" + integrity sha512-opX+7ai1sdWBOIoBgpVJrH5e89ra1KoLrJTz0UtWAa4IekkKmqDosk5r6xqRaNJfCXEfteW4HXQAwMdx+jjEmw== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.10.0" + "@typescript-eslint/types" "4.10.0" + "@typescript-eslint/typescript-estree" "4.10.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + "@typescript-eslint/parser@^2.10.0": version "2.30.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.30.0.tgz#7681c305a6f4341ae2579f5e3a75846c29eee9ce" @@ -1794,6 +1880,24 @@ "@typescript-eslint/typescript-estree" "2.30.0" eslint-visitor-keys "^1.1.0" +"@typescript-eslint/scope-manager@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.10.0.tgz#dbd7e1fc63d7363e3aaff742a6f2b8afdbac9d27" + integrity sha512-WAPVw35P+fcnOa8DEic0tQUhoJJsgt+g6DEcz257G7vHFMwmag58EfowdVbiNcdfcV27EFR0tUBVXkDoIvfisQ== + dependencies: + "@typescript-eslint/types" "4.10.0" + "@typescript-eslint/visitor-keys" "4.10.0" + +"@typescript-eslint/types@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" + integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ== + +"@typescript-eslint/types@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.10.0.tgz#12f983750ebad867f0c806e705c1953cd6415789" + integrity sha512-+dt5w1+Lqyd7wIPMa4XhJxUuE8+YF+vxQ6zxHyhLGHJjHiunPf0wSV8LtQwkpmAsRi1lEOoOIR30FG5S2HS33g== + "@typescript-eslint/typescript-estree@2.30.0": version "2.30.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.30.0.tgz#1b8e848b55144270255ffbfe4c63291f8f766615" @@ -1807,6 +1911,49 @@ semver "^6.3.0" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853" + integrity sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w== + dependencies: + "@typescript-eslint/types" "3.10.1" + "@typescript-eslint/visitor-keys" "3.10.1" + debug "^4.1.1" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/typescript-estree@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.10.0.tgz#1e62e45fd57866afd42daf5e9fb6bd4e8dbcfa75" + integrity sha512-mGK0YRp9TOk6ZqZ98F++bW6X5kMTzCRROJkGXH62d2azhghmq+1LNLylkGe6uGUOQzD452NOAEth5VAF6PDo5g== + dependencies: + "@typescript-eslint/types" "4.10.0" + "@typescript-eslint/visitor-keys" "4.10.0" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/visitor-keys@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931" + integrity sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ== + dependencies: + eslint-visitor-keys "^1.1.0" + +"@typescript-eslint/visitor-keys@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.10.0.tgz#9478822329a9bc8ebcc80623d7f79a01da5ee451" + integrity sha512-hPyz5qmDMuZWFtHZkjcCpkAKHX8vdu1G3YsCLEd25ryZgnJfj6FQuJ5/O7R+dB1ueszilJmAFMtlU4CA6se3Jg== + dependencies: + "@typescript-eslint/types" "4.10.0" + eslint-visitor-keys "^2.0.0" + "@webassemblyjs/ast@1.8.5": version "1.8.5" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" @@ -1973,6 +2120,11 @@ abab@^2.0.0: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== +abab@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -1989,6 +2141,14 @@ acorn-globals@^4.1.0, acorn-globals@^4.3.0: acorn "^6.0.1" acorn-walk "^6.0.1" +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + acorn-jsx@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" @@ -1999,6 +2159,11 @@ acorn-walk@^6.0.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + acorn@^5.5.3: version "5.7.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" @@ -2188,13 +2353,13 @@ aria-query@^3.0.0: ast-types-flow "0.0.7" commander "^2.11.0" -aria-query@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.0.2.tgz#250687b4ccde1ab86d127da0432ae3552fc7b145" - integrity sha512-S1G1V790fTaigUSM/Gd0NngzEfiMy9uTUfMyHhKhVyy4cH5O/eTuR01ydhGL0z4Za1PXFTRGH3qL8VhUQuEO5w== +aria-query@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" + integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== dependencies: - "@babel/runtime" "^7.7.4" - "@babel/runtime-corejs3" "^7.7.4" + "@babel/runtime" "^7.10.2" + "@babel/runtime-corejs3" "^7.10.2" arity-n@^1.0.4: version "1.0.4" @@ -2247,6 +2412,11 @@ array-union@^1.0.1: dependencies: array-uniq "^1.0.1" +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" @@ -2733,7 +2903,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@~3.0.2: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -3081,6 +3251,14 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + change-emitter@^0.1.2: version "0.1.6" resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" @@ -3919,11 +4097,16 @@ csso@^4.0.2: dependencies: css-tree "1.0.0-alpha.39" -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@^0.3.4: +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@^0.3.4, cssom@~0.3.6: version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + cssstyle@^1.0.0, cssstyle@^1.1.1: version "1.4.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" @@ -3931,6 +4114,13 @@ cssstyle@^1.0.0, cssstyle@^1.1.1: dependencies: cssom "0.3.x" +cssstyle@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + csstype@^2.2.0, csstype@^2.5.2, csstype@^2.6.5, csstype@^2.6.7: version "2.6.10" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b" @@ -4218,6 +4408,15 @@ data-urls@^1.0.0, data-urls@^1.1.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -4407,6 +4606,13 @@ dir-glob@2.0.0: arrify "^1.0.1" path-type "^3.0.0" +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" @@ -4449,10 +4655,10 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-accessibility-api@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.3.0.tgz#511e5993dd673b97c87ea47dba0e3892f7e0c983" - integrity sha512-PzwHEmsRP3IGY4gv/Ug+rMeaTIyTJvadCb+ujYXYeIylbHJezIyNToe8KfEgHTCEYyC+/bUghYOGg8yMGlZ6vA== +dom-accessibility-api@^0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz#b06d059cdd4a4ad9a79275f9d414a5c126241166" + integrity sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ== dom-converter@^0.2: version "0.2.0" @@ -4499,6 +4705,13 @@ domexception@^1.0.1: dependencies: webidl-conversions "^4.0.2" +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + domhandler@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" @@ -4775,6 +4988,18 @@ escodegen@^1.11.0, escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" +escodegen@^1.14.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + eslint-config-react-app@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz#698bf7aeee27f0cea0139eaef261c7bf7dd623df" @@ -4865,6 +5090,13 @@ eslint-plugin-import@^2.14.0: read-pkg-up "^2.0.0" resolve "^1.12.0" +eslint-plugin-jest@^24.1.3: + version "24.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.1.3.tgz#fa3db864f06c5623ff43485ca6c0e8fc5fe8ba0c" + integrity sha512-dNGGjzuEzCE3d5EPZQ/QGtmlMotqnYWD/QpCZ1UuZlrMAdhG5rldh0N0haCvhGnUkSeuORS5VNROwF9Hrgn3Lg== + dependencies: + "@typescript-eslint/experimental-utils" "^4.0.1" + eslint-plugin-jsx-a11y@6.2.3: version "6.2.3" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz#b872a09d5de51af70a97db1eea7dc933043708aa" @@ -4942,6 +5174,13 @@ eslint-plugin-standard@^3.1.0: resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz#2a9e21259ba4c47c02d53b2d0c9135d4b1022d47" integrity sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w== +eslint-plugin-testing-library@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.10.1.tgz#4dd02306d601c3238fdabf1d1dbc5f2a8e85d531" + integrity sha512-nQIFe2muIFv2oR2zIuXE4vTbcFNx8hZKRzgHZqJg8rfopIWwoTwtlbCCNELT/jXzVe1uZF68ALGYoDXjLczKiQ== + dependencies: + "@typescript-eslint/experimental-utils" "^3.10.1" + eslint-scope@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" @@ -4977,6 +5216,11 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== +eslint-visitor-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" + integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== + eslint@^6.6.0: version "6.8.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" @@ -5285,6 +5529,18 @@ fast-glob@^2.0.2: merge2 "^1.2.3" micromatch "^3.1.10" +fast-glob@^3.1.1: + version "3.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" + integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + fast-json-patch@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-2.1.0.tgz#e348c330a5b2481b14f5fffd707aebfef8b7bef6" @@ -5309,6 +5565,13 @@ fast-url-parser@1.1.3: dependencies: punycode "^1.3.2" +fastq@^1.6.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.9.0.tgz#e16a72f338eaca48e91b5c23593bcc2ef66b7947" + integrity sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w== + dependencies: + reusify "^1.0.4" + faye-websocket@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" @@ -5747,7 +6010,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0, glob-parent@~5.1.0: +glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== @@ -5812,6 +6075,18 @@ globby@8.0.2: pify "^3.0.0" slash "^1.0.0" +globby@^11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" + integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + globby@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" @@ -5823,7 +6098,7 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== @@ -6031,6 +6306,13 @@ html-encoding-sniffer@^1.0.2: dependencies: whatwg-encoding "^1.0.1" +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + html-entities@^1.2.1: version "1.3.1" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" @@ -6234,6 +6516,11 @@ ignore@^5.0.2: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + immer@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d" @@ -6693,6 +6980,11 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-potential-custom-element-name@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" + integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= + is-regex@^1.0.4, is-regex@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" @@ -6957,6 +7249,16 @@ jest-environment-jsdom-fourteen@1.0.1: jest-util "^24.0.0" jsdom "^14.1.0" +jest-environment-jsdom-sixteen@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom-sixteen/-/jest-environment-jsdom-sixteen-1.0.3.tgz#e222228fac537ef15cca5ad470b19b47d9690165" + integrity sha512-CwMqDUUfSl808uGPWXlNA1UFkWFgRmhHvyAjhCmCry6mYq4b/nn80MMN7tglqo5XgrANIs/w+mzINPzbZ4ZZrQ== + dependencies: + "@jest/fake-timers" "^25.1.0" + jest-mock "^25.1.0" + jest-util "^25.1.0" + jsdom "^16.2.1" + jest-environment-jsdom@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" @@ -7058,6 +7360,20 @@ jest-message-util@^24.9.0: slash "^2.0.0" stack-utils "^1.0.1" +jest-message-util@^25.5.0: + version "25.5.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.5.0.tgz#ea11d93204cc7ae97456e1d8716251185b8880ea" + integrity sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/types" "^25.5.0" + "@types/stack-utils" "^1.0.1" + chalk "^3.0.0" + graceful-fs "^4.2.4" + micromatch "^4.0.2" + slash "^3.0.0" + stack-utils "^1.0.1" + jest-mock@^24.0.0, jest-mock@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" @@ -7065,6 +7381,13 @@ jest-mock@^24.0.0, jest-mock@^24.9.0: dependencies: "@jest/types" "^24.9.0" +jest-mock@^25.1.0, jest-mock@^25.5.0: + version "25.5.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.5.0.tgz#a91a54dabd14e37ecd61665d6b6e06360a55387a" + integrity sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA== + dependencies: + "@jest/types" "^25.5.0" + jest-pnp-resolver@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" @@ -7191,6 +7514,17 @@ jest-util@^24.0.0, jest-util@^24.9.0: slash "^2.0.0" source-map "^0.6.0" +jest-util@^25.1.0, jest-util@^25.5.0: + version "25.5.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.5.0.tgz#31c63b5d6e901274d264a4fec849230aa3fa35b0" + integrity sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA== + dependencies: + "@jest/types" "^25.5.0" + chalk "^3.0.0" + graceful-fs "^4.2.4" + is-ci "^2.0.0" + make-dir "^3.0.0" + jest-validate@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" @@ -7384,6 +7718,38 @@ jsdom@^14.1.0: ws "^6.1.2" xml-name-validator "^3.0.0" +jsdom@^16.2.1: + version "16.4.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.4.0.tgz#36005bde2d136f73eee1a830c6d45e55408edddb" + integrity sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w== + dependencies: + abab "^2.0.3" + acorn "^7.1.1" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.2.0" + data-urls "^2.0.0" + decimal.js "^10.2.0" + domexception "^2.0.1" + escodegen "^1.14.1" + html-encoding-sniffer "^2.0.1" + is-potential-custom-element-name "^1.0.0" + nwsapi "^2.2.0" + parse5 "5.1.1" + request "^2.88.2" + request-promise-native "^1.0.8" + saxes "^5.0.0" + symbol-tree "^3.2.4" + tough-cookie "^3.0.1" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + ws "^7.2.3" + xml-name-validator "^3.0.0" + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -7795,11 +8161,23 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +lodash@^4.17.19: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + loglevel@^1.6.6: version "1.6.8" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171" integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA== +lolex@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" + integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== + dependencies: + "@sinonjs/commons" "^1.7.0" + longest-streak@^2.0.1: version "2.0.4" resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" @@ -7834,6 +8212,18 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lz-string@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" + integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= + make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -7842,7 +8232,7 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.2: +make-dir@^3.0.0, make-dir@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -8013,6 +8403,11 @@ merge2@^1.2.3: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -8042,6 +8437,14 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -8443,7 +8846,7 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -nwsapi@^2.0.7, nwsapi@^2.1.3: +nwsapi@^2.0.7, nwsapi@^2.1.3, nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== @@ -8866,6 +9269,11 @@ parse5@5.1.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== +parse5@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -8988,7 +9396,7 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.4, picomatch@^2.2.1: +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== @@ -9797,7 +10205,7 @@ pretty-error@^2.1.1: renderkid "^2.0.1" utila "~0.4" -pretty-format@^24.0.0, pretty-format@^24.3.0, pretty-format@^24.9.0: +pretty-format@^24.0.0, pretty-format@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== @@ -9807,15 +10215,15 @@ pretty-format@^24.0.0, pretty-format@^24.3.0, pretty-format@^24.9.0: ansi-styles "^3.2.0" react-is "^16.8.4" -pretty-format@^25.1.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a" - integrity sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ== +pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== dependencies: - "@jest/types" "^25.5.0" + "@jest/types" "^26.6.2" ansi-regex "^5.0.0" ansi-styles "^4.0.0" - react-is "^16.12.0" + react-is "^17.0.1" private@^0.1.8, private@~0.1.5: version "0.1.8" @@ -10224,11 +10632,16 @@ react-infinite-scroller@^1.2.4: dependencies: prop-types "^15.5.8" -react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6: +react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" + integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== + react-json-view@^1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.19.1.tgz#95d8e59e024f08a25e5dc8f076ae304eed97cf5c" @@ -10786,6 +11199,13 @@ request-promise-core@1.1.3: dependencies: lodash "^4.17.15" +request-promise-core@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== + dependencies: + lodash "^4.17.19" + request-promise-native@^1.0.5: version "1.0.8" resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" @@ -10795,7 +11215,16 @@ request-promise-native@^1.0.5: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.87.0, request@^2.88.0: +request-promise-native@^1.0.8: + version "1.0.9" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" + integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== + dependencies: + request-promise-core "1.1.4" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.87.0, request@^2.88.0, request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -10921,6 +11350,11 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rework-visit@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a" @@ -11026,6 +11460,11 @@ run-async@^2.2.0, run-async@^2.4.0: resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +run-parallel@^1.1.9: + version "1.1.10" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.10.tgz#60a51b2ae836636c81377df16cb107351bcd13ef" + integrity sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw== + run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" @@ -11110,6 +11549,13 @@ saxes@^3.1.9: dependencies: xmlchars "^2.1.1" +saxes@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + scheduler@^0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" @@ -11172,6 +11618,13 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@^7.3.2: + version "7.3.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== + dependencies: + lru-cache "^6.0.0" + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -11953,7 +12406,7 @@ symbol-observable@^1.0.4: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== -symbol-tree@^3.2.2: +symbol-tree@^3.2.2, symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== @@ -12173,6 +12626,15 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0, tough-cookie@~2.5 psl "^1.1.28" punycode "^2.1.1" +tough-cookie@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" + integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== + dependencies: + ip-regex "^2.1.0" + psl "^1.1.28" + punycode "^2.1.1" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -12180,6 +12642,13 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +tr46@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" + integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== + dependencies: + punycode "^2.1.1" + traverse@^0.6.6: version "0.6.6" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" @@ -12256,6 +12725,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-fest@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" @@ -12724,7 +13198,7 @@ voronoi-diagram@^1.0.1: delaunay-triangulate "^1.1.1" uniq "^1.0.1" -w3c-hr-time@^1.0.1: +w3c-hr-time@^1.0.1, w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== @@ -12740,10 +13214,12 @@ w3c-xmlserializer@^1.1.2: webidl-conversions "^4.0.2" xml-name-validator "^3.0.0" -wait-for-expect@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-3.0.2.tgz#d2f14b2f7b778c9b82144109c8fa89ceaadaa463" - integrity sha512-cfS1+DZxuav1aBYbaO/kE06EOS8yRw7qOFoD3XtjTkYvCvh3zUvNST8DXK/nPaeqIzIv3P3kL3lRJn8iwOiSag== +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" walker@^1.0.7, walker@~1.0.5: version "1.0.7" @@ -12787,6 +13263,16 @@ webidl-conversions@^4.0.2: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + webpack-dev-middleware@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" @@ -12946,6 +13432,15 @@ whatwg-url@^7.0.0: tr46 "^1.0.1" webidl-conversions "^4.0.2" +whatwg-url@^8.0.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.4.0.tgz#50fb9615b05469591d2b2bd6dfaed2942ed72837" + integrity sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^2.0.2" + webidl-conversions "^6.1.0" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -13187,6 +13682,11 @@ ws@^6.1.2, ws@^6.2.1: dependencies: async-limiter "~1.0.0" +ws@^7.2.3: + version "7.4.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb" + integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ== + x-is-string@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" @@ -13197,7 +13697,7 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== -xmlchars@^2.1.1: +xmlchars@^2.1.1, xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== diff --git a/nomad/app/.gitignore b/nomad/app/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ecdef5b83e63c1bd5adfe817f88e92dd8e09521d --- /dev/null +++ b/nomad/app/.gitignore @@ -0,0 +1 @@ +static \ No newline at end of file diff --git a/nomad/app/api/archive.py b/nomad/app/api/archive.py index 987206a93d643e49906ff7189713aa7210c56133..dcc8c968e1f02abee1abbdcbffa40ec46e7f2e00 100644 --- a/nomad/app/api/archive.py +++ b/nomad/app/api/archive.py @@ -25,7 +25,6 @@ from typing import Dict, Any from io import BytesIO from flask import request, g from flask_restplus import abort, Resource, fields -import json import orjson import urllib.parse @@ -163,6 +162,15 @@ class ArchiveDownloadResource(Resource): for entry in calcs: upload_id = entry['upload_id'] calc_id = entry['calc_id'] + + manifest = { + calc_id: { + key: entry[key] + for key in ArchiveDownloadResource.manifest_quantities + if entry.get(key) is not None + } + } + if upload_files is None or upload_files.upload_id != upload_id: if upload_files is not None: upload_files.close() @@ -182,40 +190,21 @@ class ArchiveDownloadResource(Resource): option=orjson.OPT_INDENT_2 | orjson.OPT_NON_STR_KEYS)) yield ( - '%s.%s' % (calc_id, 'json'), calc_id, + '%s.%s' % (calc_id, 'json'), calc_id, manifest, lambda calc_id: f, lambda calc_id: f.getbuffer().nbytes) - manifest[calc_id] = { - key: entry[key] - for key in ArchiveDownloadResource.manifest_quantities - if entry.get(key) is not None - } - if upload_files is not None: upload_files.close() - try: - manifest_contents = json.dumps(manifest).encode('utf-8') - except Exception as e: - manifest_contents = json.dumps( - dict(error='Could not create the manifest: %s' % (e))).encode('utf-8') - common.logger.error( - 'could not create raw query manifest', exc_info=e) - - yield ( - 'manifest.json', 'manifest', - lambda *args: BytesIO(manifest_contents), - lambda *args: len(manifest_contents)) - except Exception as e: - common.logger.warning( + common.logger.error( 'unexpected error while streaming raw data from query', exc_info=e, query=urllib.parse.urlencode(request.args, doseq=True)) return streamed_zipfile( - generator(), zipfile_name='nomad_archive.zip', compress=compress) + generator(), zipfile_name='nomad_archive.zip', compress=compress, manifest=dict()) _archive_query_model = api.inherit('ArchiveSearch', search_model, { diff --git a/nomad/app/api/common.py b/nomad/app/api/common.py index 82b3a3bc0f30f19cea84d6bf252818e169e9e3e8..23930679a2f204a05db7677c4bab4ad5f8d2fc4d 100644 --- a/nomad/app/api/common.py +++ b/nomad/app/api/common.py @@ -34,7 +34,7 @@ import os.path import gzip from functools import wraps -from nomad import search, config, datamodel +from nomad import search, config, datamodel, utils from nomad.app.optimade import filterparser from nomad.app.common import RFC3339DateTime, rfc3339DateTime from nomad.files import Restricted @@ -282,19 +282,22 @@ def upload_route(ns, prefix: str = ''): def streamed_zipfile( - files: Iterable[Tuple[str, str, Callable[[str], IO], Callable[[str], int]]], - zipfile_name: str, compress: bool = False): + files: Iterable[Tuple[str, str, dict, Callable[[str], IO], Callable[[str], int]]], + zipfile_name: str, compress: bool = False, manifest: dict = None): ''' Creates a response that streams the given files as a streamed zip file. Ensures that each given file is only streamed once, based on its filename in the resulting zipfile. Arguments: files: An iterable of tuples with the filename to be used in the resulting zipfile, - an file id within the upload, a callable that gives an binary IO object for the - file id, and a callable that gives the file size for the file id. + an file id within the upload, an optional manifest, a callable that gives an + binary IO object for the file id, and a callable that gives the file size for + the file id. zipfile_name: A name that will be used in the content disposition attachment used as an HTTP respone. compress: Uses compression. Default is stored only. + manifest: The dict contents of the manifest file. Will be extended if the files + provide manifest information. ''' streamed_files: Set[str] = set() @@ -306,11 +309,16 @@ def streamed_zipfile( Replace the directory based iter of zipstream with an iter over all given files. ''' + collected_manifest = manifest # the actual contents - for zipped_filename, file_id, open_io, file_size in files: + for zipped_filename, file_id, manifest_part, open_io, file_size in files: + if manifest_part is not None: + if collected_manifest is None: + collected_manifest = {} + collected_manifest.update(manifest_part) + if zipped_filename in streamed_files: continue - streamed_files.add(zipped_filename) # Write a file to the zipstream. try: @@ -319,7 +327,7 @@ def streamed_zipfile( def iter_content(): while True: data = f.read(1024 * 64) - if not data: + if len(data) == 0: break yield data @@ -335,6 +343,21 @@ def streamed_zipfile( # due to the streaming nature, we cannot raise 401 here # we just leave it out in the download pass + except Exception as e: + utils.get_logger('__name__').error( + 'unexpected exception while streaming zipfile', exc_info=e) + manifest.setdefault('errors', []).append( + 'unexpected exception while streaming zipfile: %s' % str(e)) + + try: + if collected_manifest is not None: + manifest_content = json.dumps(collected_manifest).encode('utf-8') + yield dict( + arcname='manifest.json', iterable=[manifest_content], + buffer_size=len(manifest_content)) + except Exception as e: + utils.get_logger('__name__').error( + 'could not stream zipfile manifest', exc_info=e) compression = zipfile.ZIP_DEFLATED if compress else zipfile.ZIP_STORED zip_stream = zipstream.ZipFile(mode='w', compression=compression, allowZip64=True) @@ -386,8 +409,11 @@ data = response.json()'''.format( def _filter_api_query(query): def normalize_value(key, value): quantity = search.search_quantities.get(key) - if quantity.many and not isinstance(value, list): - return [value] + if quantity.many: + if not isinstance(value, list): + return [value] + else: + return value elif isinstance(value, list) and len(value) == 1: return value[0] diff --git a/nomad/app/api/encyclopedia.py b/nomad/app/api/encyclopedia.py index 70cbf794075448626b6504055ba3e46489ee2f86..db16692bc623bfea5267da63a499fcfb1e909b45 100644 --- a/nomad/app/api/encyclopedia.py +++ b/nomad/app/api/encyclopedia.py @@ -28,6 +28,7 @@ from flask_restplus import Resource, abort, fields, marshal from flask import request, g from elasticsearch_dsl import Search, Q, A from elasticsearch_dsl.utils import AttrDict +import ase.data from nomad import config, infrastructure, search from nomad.files import UploadFiles @@ -395,22 +396,22 @@ class EncMaterialResource(Resource): re_formula = re.compile(r"([A-Z][a-z]?)(\d*)") range_query = api.model("range_query", { - "max": fields.Float, - "min": fields.Float, + "max": fields.Float(min=0), + "min": fields.Float(min=0), }) materials_query = api.model("materials_input", { "search_by": fields.Nested(api.model("search_query", { "exclusive": fields.Boolean(default=False, description="Set to True to enable exclusive element search."), - "formula": fields.String(description="Chemical formula of the material as a string. The order of elements does not matter.", example="TiO2"), - "elements": fields.List(fields.String, description="List of chemical species that the material should include. Use capitalized element name abbreviations.", example=["Ti", "O"]), - "page": fields.Integer(default=1, description="Requested page number, indexing starts from 1.", example=1), - "per_page": fields.Integer(default=25, description="Number of results per page.", example=10), + "formula": fields.String(description="Chemical formula of the material as a string. Use a single continuous string with capitalized element names and integer numbers for the element multiplicity. The order of elements does not matter.", example="TiO2"), + "elements": fields.List(fields.String(enum=ase.data.chemical_symbols[1:]), description="List of chemical species that the material should include. Use capitalized element name abbreviations.", example=["Ti", "O"]), + "page": fields.Integer(default=1, min=1, description="Requested page number, indexing starts from 1.", example=1), + "per_page": fields.Integer(default=25, min=1, description="Number of results per page.", example=10), "restricted": fields.Boolean(default=False, description="Select to restrict the query to individual calculations. If not selected, the query will combine results from several different calculations."), })), "material_type": fields.List(fields.String(enum=list(Material.material_type.type)), description=Material.material_type.description), "material_name": fields.List(fields.String, description=Material.material_name.description), "structure_type": fields.List(fields.String, description=Bulk.structure_type.description), - "space_group_number": fields.List(fields.Integer, description=Bulk.space_group_number.description), + "space_group_number": fields.List(fields.Integer, min=1, max=230, description=Bulk.space_group_number.description), "crystal_system": fields.List(fields.String(enum=list(Bulk.crystal_system.type)), description=Bulk.crystal_system.description), "band_gap": fields.Nested(range_query, description="Band gap range in eV.", allow_null=True), "has_band_structure": fields.Boolean(description="Set to True if electronic band structure needs to be available for this material."), @@ -485,33 +486,24 @@ class EncMaterialsResource(Resource): for f in calc_filters: s.add_calculation_filter(f) - # if data["functional_type"] is not None: s.add_calculation_filter(Q("terms", calculations__method__functional_type=data["functional_type"])) - # if data["basis_set"] is not None: s.add_calculation_filter(Q("terms", calculations__method__basis_set=data["basis_set"])) - # if data["code_name"] is not None: s.add_calculation_filter(Q("terms", calculations__method__program_name=data["code_name"])) - # if data["has_band_structure"] is not None: s.add_calculation_filter(Q("term", calculations__properties__has_electronic_band_structure=data["has_band_structure"])) - # if data["has_dos"] is not None: s.add_calculation_filter(Q("term", calculations__properties__has_electronic_dos=data["has_dos"])) - # if data["has_thermal_properties"] is not None: s.add_calculation_filter(Q("term", calculations__properties__has_thermodynamical_properties=data["has_thermal_properties"])) - # if data["band_gap"] is not None: s.add_calculation_filter(get_range_filter( - # "calculations.properties.band_gap", - # minimum=data["band_gap"].get("min"), - # maximum=data["band_gap"].get("max"), - # source_unit=ureg.eV, - # target_unit=ureg.J, - # )) - - formula = search_by["formula"] - elements = search_by["elements"] - exclusive = search_by["exclusive"] - # The given list of species/formula is reformatted with the Hill system into a # query string. With exclusive search we look for exact match, with # non-exclusive search we look for match that includes at least all # species, possibly even more. + formula = search_by["formula"] + elements = search_by["elements"] + exclusive = search_by["exclusive"] if formula is not None: element_list = [] matches = re_formula.finditer(formula) + prev_end = 0 + invalid = False for match in matches: + if match.start() != prev_end: + invalid = True + break + prev_end = match.end() groups = match.groups() symbol = groups[0] count = groups[1] @@ -520,6 +512,14 @@ class EncMaterialsResource(Resource): element_list.append(symbol) else: element_list += [symbol] * int(count) + if prev_end != len(formula) or len(element_list) == 0: + invalid = True + if invalid: + abort(400, message=( + "Invalid chemical formula provided. Please use a single " + "continuous string with capitalized element names and " + "integer numbers for the element multiplicity. E.g. 'TiO2'" + )) names, reduced_counts = get_hill_decomposition(element_list, reduced=True) query_string = [] @@ -1248,52 +1248,55 @@ class EncCalculationResource(Resource): # Add results from archive for key, arch_path in arch_properties.items(): - value = root[arch_path] - - # Replace unnormalized thermodynamical properties with - # normalized ones and turn into dict - if key == "thermodynamical_properties": - specific_heat_capacity = value.specific_heat_capacity.magnitude.tolist() - specific_free_energy = value.specific_vibrational_free_energy_at_constant_volume.magnitude.tolist() - specific_heat_capacity = [x if np.isfinite(x) else None for x in specific_heat_capacity] - specific_free_energy = [x if np.isfinite(x) else None for x in specific_free_energy] - if isinstance(value, list): - value = [x.m_to_dict() for x in value] - else: - value = value.m_to_dict() - if key == "thermodynamical_properties": - del value["thermodynamical_property_heat_capacity_C_v"] - del value["vibrational_free_energy_at_constant_volume"] - value["specific_heat_capacity"] = specific_heat_capacity - value["specific_vibrational_free_energy_at_constant_volume"] = specific_free_energy - - # DOS results are simplified. - if key == "electronic_dos": - if "dos_energies_normalized" in value: - value["dos_energies"] = value["dos_energies_normalized"] - del value["dos_energies_normalized"] - if "dos_values_normalized" in value: - value["dos_values"] = value["dos_values_normalized"] - del value["dos_values_normalized"] - - # Pre-calculate k-path length to be used as x-coordinate in - # plots. If the VBM and CBM information is needed later, it - # can be added as indices along the path. The exact k-points - # and occupations are removed to save some bandwidth. - if key == "electronic_band_structure" or key == "phonon_band_structure": - segments = value["section_k_band_segment"] - k_path_length = 0 - for segment in segments: - k_points = np.array(segment["band_k_points"]) - segment_length = np.linalg.norm(k_points[-1, :] - k_points[0, :]) - k_path_distances = k_path_length + np.linalg.norm(k_points - k_points[0, :], axis=1) - k_path_length += segment_length - segment["k_path_distances"] = k_path_distances.tolist() - del segment["band_k_points"] - if "band_occupations" in segment: - del segment["band_occupations"] - - result[key] = value + try: + value = root[arch_path] + + # Replace unnormalized thermodynamical properties with + # normalized ones and turn into dict + if key == "thermodynamical_properties": + specific_heat_capacity = value.specific_heat_capacity.magnitude.tolist() + specific_free_energy = value.specific_vibrational_free_energy_at_constant_volume.magnitude.tolist() + specific_heat_capacity = [x if np.isfinite(x) else None for x in specific_heat_capacity] + specific_free_energy = [x if np.isfinite(x) else None for x in specific_free_energy] + if isinstance(value, list): + value = [x.m_to_dict() for x in value] + else: + value = value.m_to_dict() + if key == "thermodynamical_properties": + del value["thermodynamical_property_heat_capacity_C_v"] + del value["vibrational_free_energy_at_constant_volume"] + value["specific_heat_capacity"] = specific_heat_capacity + value["specific_vibrational_free_energy_at_constant_volume"] = specific_free_energy + + # DOS results are simplified. + if key == "electronic_dos": + if "dos_energies_normalized" in value: + value["dos_energies"] = value["dos_energies_normalized"] + del value["dos_energies_normalized"] + if "dos_values_normalized" in value: + value["dos_values"] = value["dos_values_normalized"] + del value["dos_values_normalized"] + + # Pre-calculate k-path length to be used as x-coordinate in + # plots. If the VBM and CBM information is needed later, it + # can be added as indices along the path. The exact k-points + # and occupations are removed to save some bandwidth. + if key == "electronic_band_structure" or key == "phonon_band_structure": + segments = value["section_k_band_segment"] + k_path_length = 0 + for segment in segments: + k_points = np.array(segment["band_k_points"]) + segment_length = np.linalg.norm(k_points[-1, :] - k_points[0, :]) + k_path_distances = k_path_length + np.linalg.norm(k_points - k_points[0, :], axis=1) + k_path_length += segment_length + segment["k_path_distances"] = k_path_distances.tolist() + del segment["band_k_points"] + if "band_occupations" in segment: + del segment["band_occupations"] + + result[key] = value + except (AttributeError, KeyError): + abort(500, "Could not find the requested resource.") # Add results from ES for prop, es_source in es_properties.items(): diff --git a/nomad/app/api/raw.py b/nomad/app/api/raw.py index f0dfbc334db48b5d6f57d926e3fe6d373e4bb660..1a35093e4f029598320975dfce96d350f4b6a836 100644 --- a/nomad/app/api/raw.py +++ b/nomad/app/api/raw.py @@ -22,12 +22,10 @@ The raw API of the nomad@FAIRDI APIs. Can be used to retrieve raw calculation fi from typing import IO, Any, Union, List import os.path -from io import BytesIO from flask import request, send_file from flask_restplus import abort, Resource, fields import magic import fnmatch -import json import gzip import lzma import urllib.parse @@ -427,119 +425,15 @@ class RawFileQueryResource(Resource): The zip file will contain a ``manifest.json`` with the repository meta data. ''' logger = common.logger.bind(query=urllib.parse.urlencode(request.args, doseq=True)) - - patterns: List[str] = None try: args = _raw_file_from_query_parser.parse_args() - compress = args.get('compress', False) - strip = args.get('strip', False) - pattern = args.get('file_pattern', None) - if isinstance(pattern, str): - patterns = [pattern] - elif pattern is None: - patterns = [] - else: - patterns = pattern except Exception: - abort(400, message='bad parameter types') + abort(400, message='could not parse request arguments') search_request = search.SearchRequest() apply_search_parameters(search_request, _raw_file_from_query_parser.parse_args()) - search_request.include('calc_id', 'upload_id', 'mainfile') - - def path(entry): - return '%s/%s' % (entry['upload_id'], entry['mainfile']) - - calcs = search_request.execute_scan( - order_by='upload_id', - size=config.services.download_scan_size, - scroll=config.services.download_scan_timeout) - - if strip: - if search_request.execute()['total'] > config.raw_file_strip_cutoff: - abort(400, 'The requested download has to many files for using "strip".') - calcs = list(calcs) - paths = [path(entry) for entry in calcs] - common_prefix_len = len(utils.common_prefix(paths)) - else: - common_prefix_len = 0 - - def generator(): - try: - manifest = {} - directories = set() - upload_files = None - streamed, skipped = 0, 0 - - for entry in calcs: - upload_id = entry['upload_id'] - mainfile = entry['mainfile'] - if upload_files is None or upload_files.upload_id != upload_id: - logger.info('opening next upload for raw file streaming', upload_id=upload_id) - if upload_files is not None: - upload_files.close() - - upload_files = UploadFiles.get(upload_id) - - if upload_files is None: - logger.error('upload files do not exist', upload_id=upload_id) - continue - - def open_file(upload_filename): - return upload_files.raw_file(upload_filename, 'rb') - - upload_files._is_authorized = create_authorization_predicate( - upload_id=upload_id, calc_id=entry['calc_id']) - directory = os.path.dirname(mainfile) - directory_w_upload = os.path.join(upload_files.upload_id, directory) - if directory_w_upload not in directories: - streamed += 1 - directories.add(directory_w_upload) - for filename, file_size in upload_files.raw_file_list(directory=directory): - filename = os.path.join(directory, filename) - filename_w_upload = os.path.join(upload_files.upload_id, filename) - filename_wo_prefix = filename_w_upload[common_prefix_len:] - if len(patterns) == 0 or any( - fnmatch.fnmatchcase(os.path.basename(filename_wo_prefix), pattern) - for pattern in patterns): - yield ( - filename_wo_prefix, filename, open_file, - lambda *args, **kwargs: file_size) - else: - skipped += 1 - - if (streamed + skipped) % 10000 == 0: - logger.info('streaming raw files', streamed=streamed, skipped=skipped) - - manifest[path(entry)] = { - key: entry[key] - for key in RawFileQueryResource.manifest_quantities - if entry.get(key) is not None - } - - if upload_files is not None: - upload_files.close() - - logger.info('streaming raw file manifest') - try: - manifest_contents = json.dumps(manifest).encode('utf-8') - except Exception as e: - manifest_contents = json.dumps( - dict(error='Could not create the manifest: %s' % (e))).encode('utf-8') - logger.error('could not create raw query manifest', exc_info=e) - - yield ( - 'manifest.json', 'manifest', - lambda *args: BytesIO(manifest_contents), - lambda *args: len(manifest_contents)) - except Exception as e: - logger.warning( - 'unexpected error while streaming raw data from query', exc_info=e) - - logger.info('start streaming raw files') - return streamed_zipfile( - generator(), zipfile_name='nomad_raw_files.zip', compress=compress) + return respond_to_raw_files_query(search_request, args, logger) @api.doc('post_raw_files_from_query') @api.expect(_raw_file_from_query_model) @@ -558,28 +452,17 @@ class RawFileQueryResource(Resource): The zip file will contain a ``manifest.json`` with the repository meta data. ''' - patterns: List[str] = None try: - data_in = request.get_json() - compress = data_in.get('compress', False) - strip = data_in.get('strip', False) - pattern = data_in.get('file_pattern', None) - if isinstance(pattern, str): - patterns = [pattern] - elif pattern is None: - patterns = [] - else: - patterns = pattern - query = data_in.get('query', {}) + post_data = request.get_json() + query = post_data.get('query', {}) query_expression = {key: val for key, val in query.items() if '$' in key} except Exception: - abort(400, message='bad parameter types') + abort(400, message='could not parse request body') logger = common.logger.bind(query=urllib.parse.urlencode(query, doseq=True)) search_request = search.SearchRequest() apply_search_parameters(search_request, query) - search_request.include('calc_id', 'upload_id', 'mainfile') if query_expression: try: @@ -587,99 +470,106 @@ class RawFileQueryResource(Resource): except AssertionError as e: abort(400, str(e)) - def path(entry): - return '%s/%s' % (entry['upload_id'], entry['mainfile']) + return respond_to_raw_files_query(search_request, post_data, logger) - calcs = search_request.execute_scan( - order_by='upload_id', - size=config.services.download_scan_size, - scroll=config.services.download_scan_timeout) - if strip: - if search_request.execute()['total'] > config.raw_file_strip_cutoff: - abort(400, 'The requested download has to many files for using "strip".') - calcs = list(calcs) - paths = [path(entry) for entry in calcs] - common_prefix_len = len(utils.common_prefix(paths)) +def respond_to_raw_files_query(search_request, args, logger): + patterns: List[str] = None + try: + compress = args.get('compress', False) + strip = args.get('strip', False) + pattern = args.get('file_pattern', None) + if isinstance(pattern, str): + patterns = [pattern] + elif pattern is None: + patterns = [] else: - common_prefix_len = 0 + patterns = pattern + except Exception: + abort(400, message='bad parameter types') - def generator(): - try: - manifest = {} - directories = set() - upload_files = None - streamed, skipped = 0, 0 - - for entry in calcs: - upload_id = entry['upload_id'] - mainfile = entry['mainfile'] - if upload_files is None or upload_files.upload_id != upload_id: - logger.info('opening next upload for raw file streaming', upload_id=upload_id) - if upload_files is not None: - upload_files.close() - - upload_files = UploadFiles.get(upload_id) - - if upload_files is None: - logger.error('upload files do not exist', upload_id=upload_id) - continue - - def open_file(upload_filename): - return upload_files.raw_file(upload_filename, 'rb') - - upload_files._is_authorized = create_authorization_predicate( - upload_id=upload_id, calc_id=entry['calc_id']) - directory = os.path.dirname(mainfile) - directory_w_upload = os.path.join(upload_files.upload_id, directory) - if directory_w_upload not in directories: - streamed += 1 - directories.add(directory_w_upload) - for filename, file_size in upload_files.raw_file_list(directory=directory): - filename = os.path.join(directory, filename) - filename_w_upload = os.path.join(upload_files.upload_id, filename) - filename_wo_prefix = filename_w_upload[common_prefix_len:] - if len(patterns) == 0 or any( - fnmatch.fnmatchcase(os.path.basename(filename_wo_prefix), pattern) - for pattern in patterns): - yield ( - filename_wo_prefix, filename, open_file, - lambda *args, **kwargs: file_size) - else: - skipped += 1 - - if (streamed + skipped) % 10000 == 0: - logger.info('streaming raw files', streamed=streamed, skipped=skipped) - - manifest[path(entry)] = { - key: entry[key] - for key in RawFileQueryResource.manifest_quantities - if entry.get(key) is not None - } + search_request.include('calc_id', 'upload_id', 'mainfile') - if upload_files is not None: - upload_files.close() + def path(entry): + return '%s/%s' % (entry['upload_id'], entry['mainfile']) - logger.info('streaming raw file manifest') - try: - manifest_contents = json.dumps(manifest).encode('utf-8') - except Exception as e: - manifest_contents = json.dumps( - dict(error='Could not create the manifest: %s' % (e))).encode('utf-8') - logger.error('could not create raw query manifest', exc_info=e) + calcs = search_request.execute_scan( + order_by='upload_id', + size=config.services.download_scan_size, + scroll=config.services.download_scan_timeout) - yield ( - 'manifest.json', 'manifest', - lambda *args: BytesIO(manifest_contents), - lambda *args: len(manifest_contents)) + if strip: + if search_request.execute()['total'] > config.raw_file_strip_cutoff: + abort(400, 'The requested download has to many files for using "strip".') + calcs = list(calcs) + paths = [path(entry) for entry in calcs] + common_prefix_len = len(utils.common_prefix(paths)) + else: + common_prefix_len = 0 - except Exception as e: - logger.warning( - 'unexpected error while streaming raw data from query', exc_info=e) + def generator(): + try: + directories = set() + upload_files = None + streamed, skipped = 0, 0 - logger.info('start streaming raw files') - return streamed_zipfile( - generator(), zipfile_name='nomad_raw_files.zip', compress=compress) + for entry in calcs: + manifest = { + path(entry): { + key: entry[key] + for key in RawFileQueryResource.manifest_quantities + if entry.get(key) is not None + } + } + + upload_id = entry['upload_id'] + mainfile = entry['mainfile'] + if upload_files is None or upload_files.upload_id != upload_id: + logger.info('opening next upload for raw file streaming', upload_id=upload_id) + if upload_files is not None: + upload_files.close() + + upload_files = UploadFiles.get(upload_id) + + if upload_files is None: + logger.error('upload files do not exist', upload_id=upload_id) + continue + + def open_file(upload_filename): + return upload_files.raw_file(upload_filename, 'rb') + + upload_files._is_authorized = create_authorization_predicate( + upload_id=upload_id, calc_id=entry['calc_id']) + directory = os.path.dirname(mainfile) + directory_w_upload = os.path.join(upload_files.upload_id, directory) + if directory_w_upload not in directories: + streamed += 1 + directories.add(directory_w_upload) + for filename, file_size in upload_files.raw_file_list(directory=directory): + filename = os.path.join(directory, filename) + filename_w_upload = os.path.join(upload_files.upload_id, filename) + filename_wo_prefix = filename_w_upload[common_prefix_len:] + if len(patterns) == 0 or any( + fnmatch.fnmatchcase(os.path.basename(filename_wo_prefix), pattern) + for pattern in patterns): + yield ( + filename_wo_prefix, filename, manifest, open_file, + lambda *args, **kwargs: file_size) + else: + skipped += 1 + + if (streamed + skipped) % 10000 == 0: + logger.info('streaming raw files', streamed=streamed, skipped=skipped) + + if upload_files is not None: + upload_files.close() + + except Exception as e: + logger.error('unexpected error while streaming raw data from query', exc_info=e) + + logger.info('start streaming raw files') + return streamed_zipfile( + generator(), zipfile_name='nomad_raw_files.zip', compress=compress, manifest=dict()) def respond_to_get_raw_files(upload_id, files, compress=False, strip=False): @@ -696,7 +586,7 @@ def respond_to_get_raw_files(upload_id, files, compress=False, strip=False): try: return streamed_zipfile( [( - filename[common_prefix_len:], filename, + filename[common_prefix_len:], filename, None, lambda upload_filename: upload_files.raw_file(upload_filename, 'rb'), lambda upload_filename: upload_files.raw_file_size(upload_filename) ) for filename in files], diff --git a/nomad/app/api/repo.py b/nomad/app/api/repo.py index c91a277b7cb832900d062ac372f4584dbf5e52d4..75b6da960056632a55e1ab9a1a25796d0f6e3147 100644 --- a/nomad/app/api/repo.py +++ b/nomad/app/api/repo.py @@ -29,7 +29,7 @@ from elasticsearch.exceptions import NotFoundError import elasticsearch.helpers from datetime import datetime -from nomad import search, utils, datamodel, processing as proc, infrastructure, files +from nomad import search, utils, datamodel, processing as proc, infrastructure, files, metainfo from nomad.datamodel import Dataset, User, EditableUserMetadata from nomad.app import common from nomad.app.common import RFC3339DateTime, DotKeyNested @@ -465,6 +465,7 @@ _repo_edit_model = api.model('RepoEdit', { api.model('RepoEditActions', { quantity.name: repo_edit_action_field(quantity) for quantity in EditableUserMetadata.m_def.definitions + if isinstance(quantity, metainfo.Quantity) }), skip_none=True, description='Each action specifies a single value (even for multi valued quantities).'), 'success': fields.Boolean(description='If the overall edit can/could be done. Only in API response.'), diff --git a/nomad/app/api/upload.py b/nomad/app/api/upload.py index 6282cdc6db22a724b5924bfbbd1bfa92b7ba418b..bff6180e6e95dbf17a0cfe6ea6c1e8082c8b741e 100644 --- a/nomad/app/api/upload.py +++ b/nomad/app/api/upload.py @@ -31,7 +31,7 @@ import os import io from functools import wraps -from nomad import config, utils, files, search +from nomad import config, utils, files, search, datamodel from nomad.processing import Upload, FAILURE from nomad.processing import ProcessAlreadyRunning from nomad.app import common @@ -81,6 +81,8 @@ upload_model = api.inherit('UploadProcessing', proc_model, { 'upload_path': fields.String(description='The uploaded file on the server'), 'published': fields.Boolean(description='If this upload is already published'), 'upload_time': RFC3339DateTime(), + 'last_status_message': fields.String(description='The last informative message that the processing saved about this uploads status.'), + 'published_to': fields.List(fields.String(), description='A list of other NOMAD deployments that this upload was uploaded to already.') }) upload_list_model = api.model('UploadList', { @@ -123,6 +125,10 @@ upload_metadata_parser.add_argument('name', type=str, help='An optional name for upload_metadata_parser.add_argument('local_path', type=str, help='Use a local file on the server.', location='args') upload_metadata_parser.add_argument('token', type=str, help='Upload token to authenticate with curl command.', location='args') upload_metadata_parser.add_argument('file', type=FileStorage, help='The file to upload.', location='files') +upload_metadata_parser.add_argument('oasis_upload_id', type=str, help='Use if this is an upload from an OASIS to the central NOMAD and set it to the upload_id.', location='args') +upload_metadata_parser.add_argument('oasis_uploader_id', type=str, help='Use if this is an upload from an OASIS to the central NOMAD and set it to the uploader\' id.', location='args') +upload_metadata_parser.add_argument('oasis_deployment_id', type=str, help='Use if this is an upload from an OASIS to the central NOMAD and set it to the OASIS\' deployment id.', location='args') + upload_list_parser = pagination_request_parser.copy() upload_list_parser.add_argument('state', type=str, help='List uploads with given state: all, unpublished, published.', location='args') @@ -249,8 +255,35 @@ class UploadListResource(Resource): if Upload.user_uploads(g.user, published=False).count() >= config.services.upload_limit: abort(400, 'Limit of unpublished uploads exceeded for user.') + # check if allowed to perform oasis upload + oasis_upload_id = request.args.get('oasis_upload_id') + oasis_uploader_id = request.args.get('oasis_uploader_id') + oasis_deployment_id = request.args.get('oasis_deployment_id') + user = g.user + from_oasis = oasis_upload_id is not None + if from_oasis: + if not g.user.is_oasis_admin: + abort(401, 'Only an oasis admin can perform an oasis upload.') + if oasis_uploader_id is None: + abort(400, 'You must provide the original uploader for an oasis upload.') + if oasis_deployment_id is None: + abort(400, 'You must provide the oasis deployment id for an oasis upload.') + user = datamodel.User.get(user_id=oasis_uploader_id) + if user is None: + abort(400, 'The given original uploader does not exist.') + elif oasis_uploader_id is not None or oasis_deployment_id is not None: + abort(400, 'For an oasis upload you must provide an oasis_upload_id.') + upload_name = request.args.get('name') - upload_id = utils.create_uuid() + if oasis_upload_id is not None: + upload_id = oasis_upload_id + try: + Upload.get(upload_id) + abort(400, 'An oasis upload with the given upload_id already exists.') + except KeyError: + pass + else: + upload_id = utils.create_uuid() logger = common.logger.bind(upload_id=upload_id, upload_name=upload_name) logger.info('upload created', ) @@ -306,11 +339,13 @@ class UploadListResource(Resource): upload = Upload.create( upload_id=upload_id, - user=g.user, + user=user, name=upload_name, upload_time=datetime.utcnow(), upload_path=upload_path, - temporary=local_path != upload_path) + temporary=local_path != upload_path, + from_oasis=from_oasis, + oasis_deployment_id=oasis_deployment_id) upload.process_upload() logger.info('initiated processing') @@ -448,7 +483,8 @@ class UploadResource(Resource): @authenticate(required=True) def post(self, upload_id): ''' - Execute an upload operation. Available operations are ``publish`` and ``re-process`` + Execute an upload operation. Available operations are ``publish``, ``re-process``, + ``publish-to-central-nomad``. Publish accepts further meta data that allows to provide coauthors, comments, external references, etc. See the model for details. The fields that start with @@ -460,6 +496,9 @@ class UploadResource(Resource): Re-process will re-process the upload and produce updated repository metadata and archive. Only published uploads that are not processing at the moment are allowed. Only for uploads where calculations have been processed with an older nomad version. + + Publish-to-central-nomad will upload the upload to the central NOMAD. This is only + available on an OASIS. The upload must already be published on the OASIS. ''' try: upload = Upload.get(upload_id) @@ -504,7 +543,7 @@ class UploadResource(Resource): return upload, 200 elif operation == 're-process': if upload.tasks_running or upload.process_running or not upload.published: - abort(400, message='Can only non processing, re-process published uploads') + abort(400, message='Can only re-process on non processing and published uploads') if len(metadata) > 0: abort(400, message='You can not provide metadata for re-processing') @@ -514,7 +553,18 @@ class UploadResource(Resource): upload.reset() upload.re_process_upload() + return upload, 200 + elif operation == 'publish-to-central-nomad': + if upload.tasks_running or upload.process_running or not upload.published: + abort(400, message='Can only upload non processing and published uploads to central NOMAD.') + + if len(metadata) > 0: + abort(400, message='You can not provide metadata for publishing to central NOMAD') + + if not config.keycloak.oasis: + abort(400, message='This operation is only available on a NOMAD OASIS.') + upload.publish_from_oasis() return upload, 200 abort(400, message='Unsupported operation %s.' % operation) @@ -538,7 +588,8 @@ class UploadCommandResource(Resource): def get(self): ''' Get url and example command for shell based uploads. ''' token = generate_upload_token(g.user) - upload_url = '%s/uploads/?token=%s' % (config.api_url(ssl=False), token) + upload_url = ('%s/uploads/?token=%s' % + (config.api_url(ssl=config.services.https_upload), token)) upload_url_with_name = upload_url + '&name=' # upload_command = 'curl -X PUT "%s" -F file=@' % upload_url diff --git a/nomad/app/encyclopedia.py b/nomad/app/encyclopedia.py index b02769c55a80b33f504ab4fb1c7f1a71e0b364df..93dbf1369329be50f923da0f9777cb5beadd00df 100644 --- a/nomad/app/encyclopedia.py +++ b/nomad/app/encyclopedia.py @@ -19,6 +19,5 @@ from flask import Blueprint import os.path -gui_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '../../dependencies/encyclopedia-gui/client')) +gui_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), 'static/encyclopedia')) blueprint = Blueprint('encyclopedia', __name__, static_url_path='/', static_folder=gui_folder) diff --git a/nomad/app/gui.py b/nomad/app/gui.py index 33aa128a8fef7692a554912147c56f724ac450a8..7c0b9619a093f7d77645452eefb74dcd5d5ebde6 100644 --- a/nomad/app/gui.py +++ b/nomad/app/gui.py @@ -19,8 +19,10 @@ from flask import Blueprint, request import os.path -gui_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '../../gui/build')) +gui_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), 'static/gui')) +configuired_gui_folder = os.path.join(gui_folder, '../.gui_configured') +if os.path.exists(configuired_gui_folder): + gui_folder = configuired_gui_folder blueprint = Blueprint('gui', __name__, static_url_path='/', static_folder=gui_folder) diff --git a/nomad/app/optimade/calculations.py b/nomad/app/optimade/calculations.py index f47203f864bf1f7066b2b720d33bbfd3433d01a1..f4cebb766ed87a658a9128add64e853cfd820a17 100644 --- a/nomad/app/optimade/calculations.py +++ b/nomad/app/optimade/calculations.py @@ -44,11 +44,23 @@ class CalculationList(Resource): filter = request.args.get('filter', None) page_limit = int(request.args.get('page_limit', 10)) page_number = int(request.args.get('page_number', 1)) - sort = request.args.get('sort', 'chemical_formula_reduced') + sort = request.args.get('sort', request.args.get('sort', 'chemical_formula_reduced')) + + order = 1 + if sort[0:1] == '-': + order = -1 + sort = sort[1:] except Exception: abort(400, message='bad parameter types') # TODO Specific json API error handling + sort_quantity = OptimadeEntry.m_def.all_quantities.get(sort, None) + if sort_quantity is None: + abort(400, message='cannot sort by %s' % sort) # TODO Specific json API error handling + sort_quantity_a_optimade = sort_quantity.m_get_annotations('optimade') + if not sort_quantity_a_optimade.sortable: + abort(400, message='cannot sort by %s' % sort) # TODO Specific json API error handling + search_request = base_search_request().include('calc_id', 'upload_id') if filter is not None: @@ -59,8 +71,9 @@ class CalculationList(Resource): result = search_request.execute_paginated( page=page_number, - per_page=page_limit) - # order_by='optimade.%s' % sort) # TODO map the Optimade property + per_page=page_limit, + order=order, + order_by='dft.optimade.%s' % sort) returned = result['pagination']['total'] results = to_calc_with_metadata(result['results']) @@ -71,7 +84,7 @@ class CalculationList(Resource): query=request.url, returned=returned, available=nentries(), - last_id=results[-1].calc_id if returned > 0 else None), + last_id=results[-1].calc_id if len(results) > 0 else None), links=LinksModel( 'calculations', returned=returned, diff --git a/nomad/app/optimade/filterparser.py b/nomad/app/optimade/filterparser.py index 0147802d27f47a5d840c5d9fe18ddc0146c457a5..48246a07130d6cb29e3c6352281fa5545be2ba13 100644 --- a/nomad/app/optimade/filterparser.py +++ b/nomad/app/optimade/filterparser.py @@ -46,7 +46,6 @@ def _get_transformer(nomad_properties, without_prefix): if 'search' in q.m_annotations} quantities['elements'].length_quantity = quantities['nelements'] - quantities['dimension_types'].length_quantity = quantities['dimension_types'] quantities['elements'].has_only_quantity = Quantity(name='only_atoms') quantities['elements'].nested_quantity = quantities['elements_ratios'] quantities['elements_ratios'].nested_quantity = quantities['elements_ratios'] diff --git a/nomad/app/optimade/infolinks.py b/nomad/app/optimade/infolinks.py index 0c0d52a6f2f45f957330f47ecfbd5918fa1db77c..dfd82af6562d6aff898b0133d54a3bc70f7285f9 100644 --- a/nomad/app/optimade/infolinks.py +++ b/nomad/app/optimade/infolinks.py @@ -48,7 +48,7 @@ class Info(Resource): }], 'formats': ['json'], 'entry_types_by_format': { - 'json': ['structures', 'calculations', 'info'] + 'json': ['structures', 'calculations'] }, 'available_endpoints': ['structures', 'calculations', 'info'], 'is_index': False @@ -73,11 +73,12 @@ class Links(Resource): result = [ { - "type": "parent", + "type": "links", "id": "index", "attributes": { "name": config.meta.name, "description": config.meta.description, + "link_type": "root", "base_url": { "href": url(version=None, prefix='index'), }, diff --git a/nomad/app/optimade/models.py b/nomad/app/optimade/models.py index 63bdeeeb0e5c1ca00b80448a770aaf5c86fc02dd..36240d774f18d46bff4f613b3f640958c4b31514 100644 --- a/nomad/app/optimade/models.py +++ b/nomad/app/optimade/models.py @@ -25,9 +25,12 @@ from flask_restplus import fields import datetime import math from cachetools import cached +import numpy as np from nomad import config, datamodel, files from nomad.app.common import RFC3339DateTime +from nomad.normalizing.optimade import optimade_chemical_formula_reduced +from nomad.metainfo import Datetime, MEnum, MSection from nomad.datamodel import EntryMetadata from nomad.datamodel.dft import DFTMetadata from nomad.datamodel.optimade import OptimadeEntry @@ -234,15 +237,42 @@ json_api_info_model = api.model('CalculationInfo', { @cached({}) def get_entry_properties(include_optimade: bool = True): - properties = { - attr.name: dict(description=attr.description) - for attr in OptimadeEntry.m_def.all_properties.values() - if include_optimade} + properties = {} + if include_optimade: + for attr in OptimadeEntry.m_def.all_properties.values(): + prop = dict(description=attr.description) + a_optimade = attr.m_get_annotations('optimade') + if a_optimade is not None: + if a_optimade.type is not None: + prop['type'] = a_optimade.type + if a_optimade.sortable is not None: + prop['sortable'] = a_optimade.sortable def add_nmd_properties(prefix, section_cls): for quantity in section_cls.m_def.all_quantities.values(): name = prefix + quantity.name - properties[name] = dict(description=quantity.description) + if quantity.is_scalar: + if quantity.type == int: + prop_type = 'integer' + elif quantity.type == float: + prop_type = 'float' + elif quantity.type == str: + prop_type = 'string' + elif quantity.type == bool: + prop_type = 'boolean' + elif quantity.type == Datetime: + prop_type = 'timestamp' + elif isinstance(quantity.type, MEnum): + prop_type = 'string' + elif isinstance(quantity.type, np.dtype): + prop_type = 'float' + else: + prop_type = 'unknown' + else: + prop_type = 'list' + properties[name] = dict( + description=quantity.description if quantity.description else quantity.name, + type=prop_type) add_nmd_properties('_nmd_', EntryMetadata) add_nmd_properties('_nmd_dft_', DFTMetadata) @@ -270,14 +300,34 @@ class EntryDataObject: if response_fields is not None: for request_field in response_fields: + if request_field == 'chemical_formula_reduced': + # TODO remove when this is fixed in the index + # ensure correct order of elements in formula + attrs[request_field] = optimade_chemical_formula_reduced(attrs[request_field]) + + if request_field == 'dimension_types': + # TODO remove when this is fixed in the index + # ensure correct order of elements in formula + dts = attrs[request_field] + if isinstance(dts, int): + attrs[request_field] = [1] * dts + [0] * (3 - dts) + attrs['nperiodic_dimensions'] = dts + elif isinstance(dts, list): + attrs['nperiodic_dimensions'] = sum(dts) + if not request_field.startswith('_nmd_'): continue try: if request_field.startswith('_nmd_dft_'): - attrs[request_field] = getattr(calc.dft, request_field[9:]) + response_value = getattr(calc.dft, request_field[9:]) else: - attrs[request_field] = getattr(calc, request_field[5:]) + response_value = getattr(calc, request_field[5:]) + + if isinstance(response_value, MSection): + response_value = response_value.m_to_dict() + + attrs[request_field] = response_value except AttributeError: # if unknown properties where provided, we will ignore them pass diff --git a/nomad/app/optimade/structures.py b/nomad/app/optimade/structures.py index 3ad20ea13416cee9a0bc29aa5d3c4528c9fe9479..05758611e7c195e5acafe419fbd4f0bc395939af 100644 --- a/nomad/app/optimade/structures.py +++ b/nomad/app/optimade/structures.py @@ -44,11 +44,23 @@ class StructureList(Resource): filter = request.args.get('filter', None) page_limit = int(request.args.get('page_limit', 10)) page_number = int(request.args.get('page_number', 1)) - sort = request.args.get('sort', 'chemical_formula_reduced') + sort = request.args.get('sort', request.args.get('sort', 'chemical_formula_reduced')) + + order = 1 + if sort[0:1] == '-': + order = -1 + sort = sort[1:] except Exception: abort(400, message='bad parameter types') # TODO Specific json API error handling + sort_quantity = OptimadeEntry.m_def.all_quantities.get(sort, None) + if sort_quantity is None: + abort(400, message='cannot sort by %s' % sort) # TODO Specific json API error handling + sort_quantity_a_optimade = sort_quantity.m_get_annotations('optimade') + if not sort_quantity_a_optimade.sortable: + abort(400, message='cannot sort by %s' % sort) # TODO Specific json API error handling + search_request = base_search_request().include('calc_id', 'upload_id') if filter is not None: @@ -59,8 +71,9 @@ class StructureList(Resource): result = search_request.execute_paginated( page=page_number, - per_page=page_limit) - # order_by='optimade.%s' % sort) # TODO map the Optimade property + per_page=page_limit, + order=order, + order_by='dft.optimade.%s' % sort) returned = result['pagination']['total'] results = to_calc_with_metadata(result['results']) @@ -71,7 +84,7 @@ class StructureList(Resource): query=request.url, returned=returned, available=nentries(), - last_id=results[-1].calc_id if returned > 0 else None), + last_id=results[-1].calc_id if len(results) > 0 else None), links=LinksModel( 'structures', returned=returned, diff --git a/nomad/archive.py b/nomad/archive.py index 953b51000c2eec4c61392d73b84c8df9db47f50c..31193d754c85bddfd291adfd1fd562798c01713a 100644 --- a/nomad/archive.py +++ b/nomad/archive.py @@ -29,7 +29,7 @@ import re from nomad import utils, config, infrastructure from nomad.metainfo import Quantity, Reference, Definition, MSection, Section, SubSection from nomad.datamodel import EntryArchive -from nomad.datamodel.metainfo.public import fast_access +from nomad.datamodel.metainfo.common_dft import FastAccess ''' The archive storage is made from two tiers. First the whole archive is stored in @@ -681,7 +681,7 @@ def filter_archive( def create_partial_archive(archive: EntryArchive) -> Dict: ''' Creates a partial archive JSON serializable dict that can be stored directly. - The given archive is filtered based on the metainfo category ``fast_access``. + The given archive is filtered based on the metainfo category ``FastAccess``. Selected sections and other data that they reference (recursively) comprise the resulting partial archive. @@ -708,10 +708,10 @@ def create_partial_archive(archive: EntryArchive) -> Dict: if section.m_def == EntryArchive.m_def: if definition.m_def == Quantity: return True - return fast_access.m_def in definition.categories + return FastAccess.m_def in definition.categories if isinstance(definition, Quantity) and isinstance(definition.type, Reference) \ - and fast_access.m_def in definition.categories: + and FastAccess.m_def in definition.categories: # Reference list in partial archives are not supported if definition.is_scalar: referenced = getattr(section, definition.name) @@ -719,7 +719,7 @@ def create_partial_archive(archive: EntryArchive) -> Dict: referenceds.append(referenced) if isinstance(definition, SubSection): - return fast_access.m_def in definition.categories + return FastAccess.m_def in definition.categories return True @@ -897,13 +897,13 @@ def compute_required_with_referenced(required): prop = key.split('[')[0] prop_definition = parent.all_properties[prop] if isinstance(prop_definition, SubSection): - if fast_access.m_def not in prop_definition.categories: + if FastAccess.m_def not in prop_definition.categories: raise _Incomplete() traverse(value, prop_definition.sub_section) if isinstance(prop_definition, Quantity) and isinstance(prop_definition.type, Reference): current[prop] = '*' - if fast_access.m_def not in prop_definition.categories: + if FastAccess.m_def not in prop_definition.categories: continue target_section_def = prop_definition.type.target_section_def.m_resolved() diff --git a/nomad/atomutils.py b/nomad/atomutils.py index 75fd42bcc29f76fb80ea20f15465996fbce7f3e8..c64ee1ba496051628e330e7f63e47725197e69d7 100644 --- a/nomad/atomutils.py +++ b/nomad/atomutils.py @@ -23,6 +23,9 @@ from math import gcd as gcd from functools import reduce from typing import List, Dict, Tuple, Any, Union +from ase.utils import pbc2pbc +import ase.geometry + import numpy as np from scipy.spatial import Voronoi # pylint: disable=no-name-in-module from matid.symmetry import WyckoffSet @@ -45,17 +48,120 @@ def get_summed_atomic_mass(atomic_numbers: np.ndarray) -> float: return mass -def get_volume(parallelepiped: np.ndarray) -> float: - """Calculates a volume of the given parallelepiped. +def get_volume(basis: np.ndarray) -> float: + """Calculates the volume of the given parallelepiped. + + Args: + basis: 3x3 matrix with basis vectors of a parallellepiped as rows. + + Returns: + Volume of the parallelepiped defined by the basis. + """ + return np.abs(np.linalg.det(basis)) + + +def wrap_positions( + positions: np.ndarray, + cell: np.ndarray = None, + pbc: Union[bool, np.ndarray] = True, + center: np.ndarray = [0.5, 0.5, 0.5], + eps: float = 1e-7) -> np.ndarray: + """Wraps the given position so that they are within the unit cell. If no + cell is given, scaled positions are assumed. For wrapping cartesian + positions you also need to provide the cell. + + Args: + positions: Positions of the atoms. Accepts both scaled and + cartesian positions. + cell: Lattice vectors for wrapping cartesian positions. + pbc: For each axis in the unit cell decides whether the positions will + be wrapped along this axis. + center: The position in fractional coordinates that the wrapped + positions will be nearest possible to. + eps: Small number to prevent slightly negative coordinates from being + wrapped. + """ + if not hasattr(center, '__len__'): + center = (center,) * 3 + + pbc = pbc2pbc(pbc) + shift = np.asarray(center) - 0.5 - eps + + # Don't change coordinates when pbc is False + shift[np.logical_not(pbc)] = 0.0 + + if cell is None: + fractional = positions + else: + fractional = to_scaled(positions) - shift + + for i, periodic in enumerate(pbc): + if periodic: + fractional[:, i] %= 1.0 + fractional[:, i] += shift[i] + if cell: + return np.dot(fractional, cell) + else: + return fractional + + +def to_scaled( + positions: np.ndarray, + cell: np.ndarray = None) -> np.ndarray: + """Converts cartesian positions into scaled position one using the given + cell lattice vectors as a basis. + + Args: + positions: Scaled positions. + cell: Lattice vectors. + + Returns: + The given positions in scaled coordinates. + """ + return np.linalg.solve(complete_cell(cell).T, positions.T).T + + +def to_cartesian( + positions: np.ndarray, + cell: np.ndarray = None) -> np.ndarray: + """Converts scaled positions into cartesian one using the given cell + lattice vectors as a basis. + + Args: + positions: Scaled positions. + cell: Lattice vectors. + + Returns: + The given positions in cartesian coordinates. + """ + cartesian_positions = np.dot(positions, complete_cell(cell)) + return cartesian_positions + + +def complete_cell(cell: np.ndarray) -> np.ndarray: + """Creates placeholder axes for cells with zero-dimensional lattice vectors + in order to do linear algebra. Args: - cell: The parallellepiped as 3x3 matrix with cell basis vectors as - rows. + cell: Lattice vectors. Returns: - The cell volume. + The given cell with zero-dimensional lattice vectors filled with + placeholder axes. """ - return np.abs(np.linalg.det(parallelepiped)) + return ase.geometry.complete_cell(cell) + + +def reciprocal_cell(cell: np.ndarray) -> np.ndarray: + """Returns the reciprocal cell without the factor or 2*Pi. + + Args: + cell: Lattice vectors. + + Returns: + Reciprocal cell as a 3x3 array. + """ + return np.linalg.pinv(cell).transpose() def find_match(pos: np.array, positions: np.array, eps: float) -> Union[int, None]: @@ -79,6 +185,78 @@ def find_match(pos: np.array, positions: np.array, eps: float) -> Union[int, Non return None +def cellpar_to_cell(cellpar: np.ndarray, ab_normal: np.ndarray = [0, 0, 1], a_direction: np.ndarray = None, degrees=False) -> np.ndarray: + """Creates a 3x3 cell from the given lattice_parameters. + + The returned cell is orientated such that a and b are normal to `ab_normal` + and a is parallel to the projection of `a_direction` in the a-b plane. + + Default `a_direction` is (1,0,0), unless this is parallel to `ab_normal`, + in which case default `a_direction` is (0,0,1). + + The returned cell has the vectors va, vb and vc along the rows. The cell + will be oriented such that va and vb are normal to `ab_normal` and va will + be along the projection of `a_direction` onto the a-b plane. + + Args: + cellpar: Six lattice parameters: [a, b, c, alpha, beta, gamma]. + The following typical convention is used: + + a = length of first basis vector + b = length of second basis vector + c = length of third basis vector + alpha = angle between b and c in radians + beta = angle between a and c in radians + gamma = angle between a and b in radians + degrees: Use degrees in place of radians. + + Returns: + Six parameters (in this order) as a numpy + array. Here is an explanation of each parameter: + """ + if not degrees: + cellpar[3:6] *= 180.0 / np.pi + + return ase.geometry.cell.cellpar_to_cell(cellpar, ab_normal, a_direction) + + +def cell_to_cellpar(cell: np.ndarray, degrees=False) -> np.ndarray: + """Returns lattice parameters for the given cell. + + Args: + normalized_cell: The normalized cell as a 3x3 array. Each row is a + basis vector. + degrees: Use degrees in place of radians. + + Returns: + Six parameters [a, b, c, alpha, beta, gamma]. The following typical + convention ik used: + + a = length of first basis vector + b = length of second basis vector + c = length of third basis vector + alpha = angle between b and c in radians + beta = angle between a and c in radians + gamma = angle between a and b in radians + """ + # Lengths + lengths = np.linalg.norm(cell, axis=1) + + # Angles + angles = np.zeros(3) + for i in range(3): + j = (i + 1) % 3 + k = (i + 2) % 3 + angles[i] = np.dot( + cell[j], + cell[k]) / (lengths[j] * lengths[k]) + angles = np.arccos(np.clip(angles, -1.0, 1.0)) + if degrees: + angles *= 180.0 / np.pi + + return np.concatenate((lengths, angles), axis=0) + + def get_symmetry_string(space_group: int, wyckoff_sets: List[WyckoffSet], is_2d: bool = False) -> str: """Used to serialize symmetry information into a string. The Wyckoff positions are assumed to be normalized and ordered as is the case if using @@ -112,45 +290,6 @@ def get_symmetry_string(space_group: int, wyckoff_sets: List[WyckoffSet], is_2d: return string -def get_lattice_parameters(normalized_cell: np.ndarray) -> np.ndarray: - """Calculate the lattice parameters for the normalized cell. - - Args: - normalized_cell: The normalized cell as a 3x3 array. Each row is a - basis vector. - - Returns: - Six parameters a, b, c, alpha, beta, gamma (in this order) as a numpy - array. Here is an explanation of each parameter: - - a = length of first basis vector - b = length of second basis vector - c = length of third basis vector - alpha = angle between b and c - beta = angle between a and c - gamma = angle between a and b - """ - if normalized_cell is None: - return None - - # Lengths - lengths = np.linalg.norm(normalized_cell, axis=1) - a, b, c = lengths - - # Angles - angles = np.zeros(3) - for i in range(3): - j = (i + 1) % 3 - k = (i + 2) % 3 - angles[i] = np.dot( - normalized_cell[j], - normalized_cell[k]) / (lengths[j] * lengths[k]) - angles = np.clip(angles, -1.0, 1.0) - alpha, beta, gamma = np.arccos(angles) - - return [a, b, c, alpha, beta, gamma] - - def get_hill_decomposition(atom_labels: np.ndarray, reduced: bool = False) -> Tuple[List[str], List[int]]: """Given a list of atomic labels, returns the chemical formula using the Hill system (https://en.wikipedia.org/wiki/Hill_system) with an exception diff --git a/nomad/cli/admin/admin.py b/nomad/cli/admin/admin.py index b171273f10d6174b437db1fd1e4667e95b511a47..3ddd29e1525ee29ada8643e68d813fcbde3bc400 100644 --- a/nomad/cli/admin/admin.py +++ b/nomad/cli/admin/admin.py @@ -612,34 +612,40 @@ def restore(path_to_dump): @ops.command(help=('Generate an nginx.conf to serve the GUI and proxy pass to API container.')) -@click.option('--prefix', type=str, default='/example_nomad', help='Url path prefix. Default is /example_nomd, can be empty str.') -def nginx_conf(prefix): +@click.option('--prefix', type=str, default=config.services.api_base_path, help='Alter the url path prefix.') +@click.option('--host', type=str, default=config.services.api_host, help='Alter the NOMAD app host.') +@click.option('--port', type=str, default=config.services.api_port, help='Alter the NOMAD port host.') +@click.option('--server/--no-server', default=True, help='Control writing of the outer server {} block. ' + 'Useful when conf file is included within another nginx.conf.') +def nginx_conf(prefix, host, port, server): prefix = prefix.rstrip('/') prefix = '/%s' % prefix.lstrip('/') - print('''\ -server {{ + if server: + print('''server { listen 80; server_name www.example.com; proxy_set_header Host $host; + ''') + print(''' location / {{ - proxy_pass http://app:8000; + proxy_pass http://{1}:{2}; }} - location ~ {1}\\/?(gui)?$ {{ - rewrite ^ {1}/gui/ permanent; + location ~ {0}\\/?(gui)?$ {{ + rewrite ^ {0}/gui/ permanent; }} - location {1}/gui/ {{ + location {0}/gui/ {{ proxy_intercept_errors on; error_page 404 = @redirect_to_index; - proxy_pass http://app:8000; + proxy_pass http://{1}:{2}; }} location @redirect_to_index {{ - rewrite ^ {1}/gui/index.html break; - proxy_pass http://app:8000; + rewrite ^ {0}/gui/index.html break; + proxy_pass http://{1}:{2}; }} location ~ \\/gui\\/(service-worker\\.js|meta\\.json)$ {{ @@ -648,69 +654,39 @@ server {{ if_modified_since off; expires off; etag off; - proxy_pass http://app:8000; + proxy_pass http://{1}:{2}; }} location ~ \\/api\\/uploads\\/?$ {{ client_max_body_size 35g; proxy_request_buffering off; - proxy_pass http://app:8000; + proxy_pass http://{1}:{2}; }} location ~ \\/api\\/(raw|archive) {{ proxy_buffering off; - proxy_pass http://app:8000; + proxy_pass http://{1}:{2}; }} location ~ \\/api\\/mirror {{ proxy_buffering off; proxy_read_timeout 600; - proxy_pass http://app:8000; + proxy_pass http://{1}:{2}; }} -}}'''.format(prefix)) - - -@ops.command(help=('Generate a proxy pass config for apache2 reverse proxy servers.')) -@click.option('--prefix', type=str, default='app', help='The path prefix under which everything is proxy passed.') -@click.option('--host', type=str, default='130.183.207.104', help='The host to proxy to.') -@click.option('--port', type=str, default='30001', help='The port to proxy to.') -def apache_conf(prefix, host, port): - print('''\ -ProxyPass "/{0}" "http://{1}:{2}/{0}" -ProxyPassReverse "/{0}" "http://{1}:{2}/{0}" - - ProxyPreserveHost On - - Require all granted - - - Order allow,deny - Allow from all - - - -RequestHeader set "X-Forwarded-Proto" expr=%{{REQUEST_SCHEME}} -RequestHeader set "X-Forwarded-SSL" expr=%{{HTTPS}} - -ProxyPass /fairdi/keycloak http://{1}:8002/fairdi/keycloak -ProxyPassReverse /fairdi/keycloak http://{1}:8002/fairdi/keycloak - - ProxyPreserveHost On - - Require all granted - - - Order allow,deny - Allow from all - - - -RewriteEngine on -RewriteCond %{QUERY_STRING} ^pid=([^&]+)$ -RewriteRule ^/NomadRepository-1.1/views/calculation.zul$ /{0}/gui/entry/pid/%1? [R=301] - -AllowEncodedSlashes On -'''.format(prefix, host, port)) # type: ignore + + location ~ \\/encyclopedia\\/ {{ + proxy_intercept_errors on; + error_page 404 = @redirect_to_encyclopedia_index; + proxy_pass http://{1}:{2}; + }} + + location @redirect_to_encyclopedia_index {{ + rewrite ^ {0}/encyclopedia/index.html break; + proxy_pass http://{1}:{2}; + }} +'''.format(prefix, host, port)) + if server: + print('}') @ops.command(help='Updates the AFLOW prototype information using the latest online version and writes the results to a python module in the given FILEPATH.') @@ -746,3 +722,76 @@ def update(input_dir, out, verbose): def ingest(input_path, batch_size, verbose): from nomad.cli.admin import similarity similarity.ingest(input_path, batch_size, verbose) + + +@ops.command(help='Configures the GUIs based on NOMAD config.') +def gui_config(): + import os + import os.path + from nomad import config + import glob + import shutil + + gui_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../app/static/gui')) + run_gui_folder = os.path.join(gui_folder, '../.gui_configured') + + # copy + shutil.rmtree(run_gui_folder, ignore_errors=True) + shutil.copytree(gui_folder, run_gui_folder) + + # setup the env + env_js_file = os.path.join(run_gui_folder, 'env.js') + if not os.path.exists(env_js_file): + with open(env_js_file, 'wt') as f: + f.write((''' +window.nomadEnv = { + 'appBase': '%s', + 'keycloakBase': 'https://nomad-lab.eu/fairdi/keycloak/auth/', + 'keycloakRealm': '%s', + 'keycloakClientId': '%s', + 'debug': false, + 'matomoEnabled': false, + 'encyclopediaEnabled': true, + 'oasis': %s +};''' % ( + config.services.api_base_path, + config.keycloak.realm_name, + config.keycloak.client_id, + 'true' if config.keycloak.oasis else 'false' + ))) + + # replace base path in all GUI files + source_file_globs = [ + '**/*.json', + '**/*.html', + '**/*.js', + '**/*.js.map', + '**/*.css'] + for source_file_glob in source_file_globs: + source_files = glob.glob(os.path.join(run_gui_folder, source_file_glob), recursive=True) + for source_file in source_files: + with open(source_file, 'rt') as f: + file_data = f.read() + file_data = file_data.replace('/fairdi/nomad/latest', config.services.api_base_path) + with open(source_file, 'wt') as f: + f.write(file_data) + + gui_folder = os.path.abspath(os.path.join( + os.path.dirname(__file__), '../../app/static/encyclopedia')) + + # setup the env + conf_js_file = os.path.join(gui_folder, 'conf.js') + if not os.path.exists(conf_js_file): + with open(conf_js_file, 'wt') as f: + f.write((''' +window.nomadEnv = { + apiRoot: "%s/api/encyclopedia/", + keycloakBase: "%s", + keycloakRealm: "%s", + keycloakClientId: "%s" +};''' % ( + config.services.api_base_path, + config.keycloak.server_url, + config.keycloak.realm_name, + config.keycloak.client_id + ))) diff --git a/nomad/cli/client/client.py b/nomad/cli/client/client.py index 3c0afffd3d7b5a64a9f74b6225b81bf3045a96a8..aa41e91f4a3e724d1dd60a8d2eebbf4c428b9c7e 100644 --- a/nomad/cli/client/client.py +++ b/nomad/cli/client/client.py @@ -41,22 +41,21 @@ def _create_client(*args, **kwargs): def __create_client( user: str = nomad_config.client.user, password: str = nomad_config.client.password, + api_base_url: str = nomad_config.client.url, ssl_verify: bool = True, use_token: bool = True): ''' A factory method to create the client. ''' if not ssl_verify: import warnings warnings.filterwarnings("ignore") - http_client = bravado_requests_client.RequestsClient(ssl_verify=ssl_verify) client = bravado_client.SwaggerClient.from_url( - '%s/swagger.json' % nomad_config.client.url, - http_client=http_client) + '%s/swagger.json' % api_base_url, http_client=http_client) utils.get_logger(__name__).info('created bravado client', user=user) if user is not None: - host = urllib_parse.urlparse(nomad_config.client.url).netloc.split(':')[0] + host = urllib_parse.urlparse(api_base_url).netloc if use_token: http_client.authenticator = nomad_client.KeycloakAuthenticator( host=host, diff --git a/nomad/cli/dev.py b/nomad/cli/dev.py index a290b3704f021c2d06188f561dfd5a73b5d7a1fc..c1073cf946ce1c2f8e169587d02c95b64b61bd11 100644 --- a/nomad/cli/dev.py +++ b/nomad/cli/dev.py @@ -34,6 +34,7 @@ def dev(): def qa(skip_tests: bool, exitfirst: bool): os.chdir(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))) ret_code = 0 + if not skip_tests: click.echo('Run tests ...') ret_code += os.system('python -m pytest -sv%s tests' % ('x' if exitfirst else '')) @@ -48,11 +49,17 @@ def qa(skip_tests: bool, exitfirst: bool): @dev.command(help='Runs tests and linting of the nomad gui source code. Useful before committing code.') -def gui_qa(): - click.echo('Run gui code linting ...') +@click.option('--skip-tests', help='Do no tests, just do code checks.', is_flag=True) +def gui_qa(skip_tests: bool): os.chdir(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../gui'))) ret_code = 0 - ret_code += os.system('yarn run eslint \'src/**/*.js\'') + + if not skip_tests: + click.echo('Run gui testing ...') + ret_code += os.system('yarn run test') + click.echo('Run gui code linting ...') + ret_code += os.system('yarn run lint') + sys.exit(ret_code) @@ -73,6 +80,7 @@ def metainfo_undecorated(): import nomad.datamodel.ems import nomad.datamodel.optimade import nomad.datamodel.encyclopedia + from nomad.parsing import LegacyParser nomad.metainfo.metainfo.m_package.__init_metainfo__() nomad.datamodel.datamodel.m_package.__init_metainfo__() nomad.datamodel.dft.m_package.__init_metainfo__() # pylint: disable=no-member @@ -83,7 +91,8 @@ def metainfo_undecorated(): # Ensure all parser metainfo is loaded from nomad.parsing.parsers import parsers for parser in parsers: - _ = parser.metainfo_env + if isinstance(parser, LegacyParser): + _ = parser.metainfo_env export = Environment() for package in Package.registry.values(): @@ -121,57 +130,6 @@ def search_quantities(): print(json.dumps(export, indent=2)) -@dev.command(help='Generates source-code for the new metainfo from .json files of the old.') -@click.argument('path', nargs=-1) -def legacy_metainfo(path): - from nomad.metainfo.legacy import convert, generate_metainfo_code - - if len(path) == 0: - path = [ - 'abinit.nomadmetainfo.json', - 'aptfim.nomadmetainfo.json', - 'atk.nomadmetainfo.json', - 'band.nomadmetainfo.json', - 'bigdft.nomadmetainfo.json', - 'castep.nomadmetainfo.json', - 'cp2k.nomadmetainfo.json', - 'cpmd.nomadmetainfo.json', - 'crystal.nomadmetainfo.json', - 'dl_poly.nomadmetainfo.json', - 'dmol3.nomadmetainfo.json', - 'eels.nomadmetainfo.json', - 'elastic.nomadmetainfo.json', - 'elk.nomadmetainfo.json', - 'exciting.nomadmetainfo.json', - 'fhi_aims.nomadmetainfo.json', - 'fleur.nomadmetainfo.json', - 'gamess.nomadmetainfo.json', - 'gaussian.nomadmetainfo.json', - 'gpaw.nomadmetainfo.json', - 'gulp.nomadmetainfo.json', - 'lib_atoms.nomadmetainfo.json', - 'molcas.nomadmetainfo.json', - 'mpes.nomadmetainfo.json', - 'nwchem.nomadmetainfo.json', - 'octopus.nomadmetainfo.json', - 'onetep.nomadmetainfo.json', - 'orca.nomadmetainfo.json', - 'phonopy.nomadmetainfo.json', - 'photoemission.nomadmetainfo.json', - 'qbox.nomadmetainfo.json', - 'quantum_espresso.nomadmetainfo.json', - 'siesta.nomadmetainfo.json', - 'turbomole.nomadmetainfo.json', - 'vasp.nomadmetainfo.json', - 'wien2k.nomadmetainfo.json', - 'dft.nomadmetainfo.json', - 'ems.nomadmetainfo.json'] - - for element in path: - env = convert(element) - generate_metainfo_code(env) - - @dev.command(help='Generates a JSON file that compiles all the parser metadata from each parser project.') def parser_metadata(): import inspect diff --git a/nomad/client.py b/nomad/client.py index f29ced9f2ba35de80c33ac9f4f39ed10b3a13927..3106a16ecc6df9376c10f495d0f936ce71101003 100644 --- a/nomad/client.py +++ b/nomad/client.py @@ -17,8 +17,6 @@ # ''' -.. _install-client: - Install the NOMAD client library ________________________________ diff --git a/nomad/config.py b/nomad/config.py index 0d8ce24d074634b01b8b51ee721e1a3c472eb42a..1c704ce86ed2348e07e1e940032a271ea7c0da40 100644 --- a/nomad/config.py +++ b/nomad/config.py @@ -156,12 +156,18 @@ services = NomadConfig( not_processed_value='not processed', unavailable_value='unavailable', https=False, + https_upload=False, upload_limit=10, force_raw_file_decoding=False, download_scan_size=500, download_scan_timeout=u'30m' ) +oasis = NomadConfig( + central_nomad_api_url='https://nomad-lab.eu/prod/rae/api', + central_nomad_deployment_id='nomad-lab.eu/prod/rae' +) + tests = NomadConfig( default_timeout=30 ) @@ -204,7 +210,7 @@ def check_config(): "--matches-only'." ) - if not os.path.exists(normalize.springer_db_path): + if normalize.springer_db_path and not os.path.exists(normalize.springer_db_path): normalize.springer_db_path = None @@ -275,7 +281,7 @@ datacite = NomadConfig( ) meta = NomadConfig( - version='0.9.7', + version='0.9.8', commit=gitinfo.commit, release='devel', default_domain='dft', @@ -284,11 +290,16 @@ meta = NomadConfig( description='A FAIR data sharing platform for materials science data', homepage='https://nomad-lab.eu', source_url='https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR', - maintainer_email='markus.scheidgen@physik.hu-berlin.de' + maintainer_email='markus.scheidgen@physik.hu-berlin.de', + deployment_id='nomad-lab.eu/prod/rae' +) + +gitlab = NomadConfig( + private_token='not set' ) auxfile_cutoff = 100 -parser_matching_size = 9128 +parser_matching_size = 150 * 80 # 150 lines of 80 ASCII characters per line console_log_level = logging.WARNING max_upload_size = 32 * (1024 ** 3) raw_file_strip_cutoff = 1000 diff --git a/nomad/datamodel/__init__.py b/nomad/datamodel/__init__.py index 9d365fc52f5b10ad401fd330df37e73831b2dde9..f6cf880df3304335b25eb7ef9eba3aa732062b6c 100644 --- a/nomad/datamodel/__init__.py +++ b/nomad/datamodel/__init__.py @@ -91,8 +91,8 @@ from .dft import DFTMetadata from .ems import EMSMetadata from .qcms import QCMSMetadata from .datamodel import ( - Dataset, User, Author, EditableUserMetadata, UserProvidableMetadata, MongoMetadata, - EntryMetadata, EntryArchive) + Dataset, User, Author, EditableUserMetadata, UserProvidableMetadata, OasisMetadata, + MongoMetadata, EntryMetadata, EntryArchive) from .optimade import OptimadeEntry, Species from .metainfo import m_env diff --git a/nomad/datamodel/datamodel.py b/nomad/datamodel/datamodel.py index 9269d98f4be395d9c24f089a1f5b0b94867a655f..caab93d46c601e50f7671861283dd126eab41dca 100644 --- a/nomad/datamodel/datamodel.py +++ b/nomad/datamodel/datamodel.py @@ -27,7 +27,7 @@ from nomad import metainfo, config from nomad.metainfo.search_extension import Search from nomad.metainfo.elastic_extension import ElasticDocument from nomad.metainfo.mongoengine_extension import Mongo, MongoDocument -from nomad.datamodel.metainfo.public import fast_access +from nomad.datamodel.metainfo.common_dft import FastAccess from .dft import DFTMetadata from .ems import EMSMetadata @@ -38,9 +38,9 @@ from .qcms import QCMSMetadata m_package = metainfo.Package() from .encyclopedia import EncyclopediaMetadata # noqa -from .metainfo.public import section_run, Workflow # noqa +from .metainfo.common_dft import Run, Workflow # noqa from .metainfo.common_experimental import Experiment # noqa -from .metainfo.general_qcms import QuantumCMS # noqa +from .metainfo.common_qcms import QuantumCMS # noqa def _only_atoms(atoms): @@ -106,6 +106,8 @@ class User(Author): is_admin = metainfo.Quantity( type=bool, derived=lambda user: user.user_id == config.services.admin_user_id) + is_oasis_admin = metainfo.Quantity(type=bool, default=False) + @staticmethod @cached(cache=TTLCache(maxsize=2048, ttl=24 * 3600)) def get(*args, **kwargs) -> 'User': @@ -239,6 +241,11 @@ class EditableUserMetadata(metainfo.MCategory): m_def = metainfo.Category(categories=[UserProvidableMetadata]) +class OasisMetadata(metainfo.MCategory): + ''' NOMAD entry metadata quantities that can be provided by an OASIS. ''' + m_def = metainfo.Category(categories=[EditableUserMetadata]) + + class MongoMetadata(metainfo.MCategory): ''' NOMAD entry quantities that are stored in mongodb and not necessarely in the archive. ''' pass @@ -311,6 +318,7 @@ class EntryMetadata(metainfo.MSection): calc_id = metainfo.Quantity( type=str, description='A persistent and globally unique identifier for the entry', + categories=[OasisMetadata], a_search=Search(many_or='append')) calc_hash = metainfo.Quantity( @@ -375,7 +383,7 @@ class EntryMetadata(metainfo.MSection): published = metainfo.Quantity( type=bool, default=False, description='Indicates if the entry is published', - categories=[MongoMetadata], + categories=[MongoMetadata, OasisMetadata], a_search=Search()) processed = metainfo.Quantity( @@ -478,7 +486,7 @@ class EntryMetadata(metainfo.MSection): a_search=Search()) upload_time = metainfo.Quantity( - type=metainfo.Datetime, categories=[MongoMetadata], + type=metainfo.Datetime, categories=[MongoMetadata, OasisMetadata], description='The date and time this entry was uploaded to nomad', a_flask=dict(admin_only=True), a_search=Search(order_default=True)) @@ -511,7 +519,7 @@ class EntryMetadata(metainfo.MSection): a_search=Search(many_or='split')) last_edit = metainfo.Quantity( - type=metainfo.Datetime, categories=[MongoMetadata], + type=metainfo.Datetime, categories=[MongoMetadata, OasisMetadata], description='The date and time the user metadata was edited last', a_search=Search()) @@ -538,9 +546,9 @@ class EntryMetadata(metainfo.MSection): a_search=Search()) ems = metainfo.SubSection(sub_section=EMSMetadata, a_search='ems') - dft = metainfo.SubSection(sub_section=DFTMetadata, a_search='dft', categories=[fast_access]) + dft = metainfo.SubSection(sub_section=DFTMetadata, a_search='dft', categories=[FastAccess]) qcms = metainfo.SubSection(sub_section=QCMSMetadata, a_search='qcms') - encyclopedia = metainfo.SubSection(sub_section=EncyclopediaMetadata, categories=[fast_access], a_search='encyclopedia') + encyclopedia = metainfo.SubSection(sub_section=EncyclopediaMetadata, categories=[FastAccess], a_search='encyclopedia') def apply_user_metadata(self, metadata: dict): ''' Applies a user provided metadata dict to this calc. ''' @@ -563,11 +571,11 @@ class EntryMetadata(metainfo.MSection): class EntryArchive(metainfo.MSection): - section_run = metainfo.SubSection(sub_section=section_run, repeats=True) + section_run = metainfo.SubSection(sub_section=Run, repeats=True) section_experiment = metainfo.SubSection(sub_section=Experiment) section_quantum_cms = metainfo.SubSection(sub_section=QuantumCMS) - section_workflow = metainfo.SubSection(sub_section=Workflow, categories=[fast_access]) - section_metadata = metainfo.SubSection(sub_section=EntryMetadata, categories=[fast_access]) + section_workflow = metainfo.SubSection(sub_section=Workflow, categories=[FastAccess]) + section_metadata = metainfo.SubSection(sub_section=EntryMetadata, categories=[FastAccess]) processing_logs = metainfo.Quantity( type=Any, shape=['0..*'], diff --git a/nomad/datamodel/dft.py b/nomad/datamodel/dft.py index 59e1d9a7b2ea8052f38ada427aef46618d16eeed..8f94c09c95cca140f1254e46ebaca44755f7e2d7 100644 --- a/nomad/datamodel/dft.py +++ b/nomad/datamodel/dft.py @@ -27,8 +27,8 @@ from nomad.metainfo import MSection, Section, Quantity, MEnum, SubSection from nomad.metainfo.search_extension import Search from .optimade import OptimadeEntry -from .metainfo.public import Workflow, fast_access -from .metainfo.public import section_XC_functionals +from .metainfo.common_dft import Workflow, FastAccess +from .metainfo.common_dft import section_XC_functionals xc_treatments = { @@ -238,7 +238,7 @@ class DFTMetadata(MSection): a_search=Search(many_or='append', group='groups_grouped', metric_name='groups', metric='cardinality')) labels = SubSection( - sub_section=Label, repeats=True, categories=[fast_access], + sub_section=Label, repeats=True, categories=[FastAccess], description='The labels taken from AFLOW prototypes and springer.', a_search='labels') diff --git a/nomad/datamodel/encyclopedia.py b/nomad/datamodel/encyclopedia.py index 5b5f455f04ea673c4253c82f51e41f60e7d73d1a..5fd2f07af5159b3fd70a3f4ef5a0673e5d5307aa 100644 --- a/nomad/datamodel/encyclopedia.py +++ b/nomad/datamodel/encyclopedia.py @@ -26,7 +26,7 @@ from nomad.metainfo.search_extension import Search # due to the next imports requireing the m_package already, this would be too late. m_package = Package() -from .metainfo.public import section_k_band, section_dos, section_thermodynamical_properties, fast_access # noqa +from .metainfo.common_dft import section_k_band, section_dos, section_thermodynamical_properties, FastAccess # noqa class WyckoffVariables(MSection): @@ -82,7 +82,7 @@ class WyckoffSet(MSection): Chemical element at this Wyckoff position. """ ) - variables = SubSection(sub_section=WyckoffVariables.m_def, repeats=False, categories=[fast_access]) + variables = SubSection(sub_section=WyckoffVariables.m_def, repeats=False, categories=[FastAccess]) class LatticeParameters(MSection): @@ -208,8 +208,8 @@ class IdealizedStructure(MSection): """, a_search=Search() ) - wyckoff_sets = SubSection(sub_section=WyckoffSet.m_def, repeats=True, categories=[fast_access]) - lattice_parameters = SubSection(sub_section=LatticeParameters.m_def, categories=[fast_access]) + wyckoff_sets = SubSection(sub_section=WyckoffSet.m_def, repeats=True, categories=[FastAccess]) + lattice_parameters = SubSection(sub_section=LatticeParameters.m_def, categories=[FastAccess]) class Bulk(MSection): @@ -388,10 +388,10 @@ class Material(MSection): ) # Bulk-specific properties - bulk = SubSection(sub_section=Bulk.m_def, repeats=False, categories=[fast_access]) + bulk = SubSection(sub_section=Bulk.m_def, repeats=False, categories=[FastAccess]) # The idealized structure for this material - idealized_structure = SubSection(sub_section=IdealizedStructure.m_def, repeats=False, categories=[fast_access]) + idealized_structure = SubSection(sub_section=IdealizedStructure.m_def, repeats=False, categories=[FastAccess]) class Method(MSection): @@ -593,7 +593,7 @@ class Properties(MSection): """, a_search=Search() ) - energies = SubSection(sub_section=Energies.m_def, repeats=False, categories=[fast_access], a_search='energies') + energies = SubSection(sub_section=Energies.m_def, repeats=False, categories=[FastAccess], a_search='energies') electronic_band_structure = Quantity( type=Reference(section_k_band.m_def), shape=[], @@ -644,10 +644,10 @@ class EncyclopediaMetadata(MSection): Section which stores information for the NOMAD Encyclopedia. """ ) - material = SubSection(sub_section=Material.m_def, repeats=False, categories=[fast_access], a_search='material') - method = SubSection(sub_section=Method.m_def, repeats=False, categories=[fast_access], a_search='method') - properties = SubSection(sub_section=Properties.m_def, repeats=False, categories=[fast_access], a_search='properties') - calculation = SubSection(sub_section=Calculation.m_def, repeats=False, categories=[fast_access], a_search='calculation') + material = SubSection(sub_section=Material.m_def, repeats=False, categories=[FastAccess], a_search='material') + method = SubSection(sub_section=Method.m_def, repeats=False, categories=[FastAccess], a_search='method') + properties = SubSection(sub_section=Properties.m_def, repeats=False, categories=[FastAccess], a_search='properties') + calculation = SubSection(sub_section=Calculation.m_def, repeats=False, categories=[FastAccess], a_search='calculation') status = Quantity( type=MEnum("success", "unsupported_material_type", "unsupported_method_type", "unsupported_calculation_type", "invalid_metainfo", "failure"), description=""" diff --git a/nomad/datamodel/metainfo/__init__.py b/nomad/datamodel/metainfo/__init__.py index 8a3af683d9fd46a972a11d2128cfecf85ecc1709..f72c52263c68850bb9e83a6bce9b677f9382923f 100644 --- a/nomad/datamodel/metainfo/__init__.py +++ b/nomad/datamodel/metainfo/__init__.py @@ -19,11 +19,7 @@ import sys from nomad.metainfo import Environment from nomad.metainfo.legacy import LegacyMetainfoEnvironment -import nomad.datamodel.metainfo.common -import nomad.datamodel.metainfo.public -import nomad.datamodel.metainfo.general +import nomad.datamodel.metainfo.common_dft m_env = LegacyMetainfoEnvironment() -m_env.m_add_sub_section(Environment.packages, sys.modules['nomad.datamodel.metainfo.common'].m_package) # type: ignore -m_env.m_add_sub_section(Environment.packages, sys.modules['nomad.datamodel.metainfo.public'].m_package) # type: ignore -m_env.m_add_sub_section(Environment.packages, sys.modules['nomad.datamodel.metainfo.general'].m_package) # type: ignore +m_env.m_add_sub_section(Environment.packages, sys.modules['nomad.datamodel.metainfo.common_dft'].m_package) # type: ignore diff --git a/nomad/datamodel/metainfo/common.py b/nomad/datamodel/metainfo/common.py index 5c08eb1dde24cc680b646a071b215b0ca83556fa..4e13e59402e7dd159206d8eb67a3b141be510fd8 100644 --- a/nomad/datamodel/metainfo/common.py +++ b/nomad/datamodel/metainfo/common.py @@ -16,1339 +16,10 @@ # limitations under the License. # -import numpy as np # pylint: disable=unused-import -import typing # pylint: disable=unused-import -from nomad.metainfo import ( # pylint: disable=unused-import - MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy, - Reference -) -from nomad.metainfo.legacy import LegacyDefinition +# This is just for backward compatibility of old imports. All definitions are now in common_dft -from nomad.datamodel.metainfo import public +from nomad.metainfo import Package -m_package = Package( - name='common_nomadmetainfo_json', - description='None', - a_legacy=LegacyDefinition(name='common.nomadmetainfo.json')) +from .common_dft import * - -class settings_atom_in_molecule(MCategory): - ''' - Parameters of an atom within a molecule. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_atom_in_molecule')) - - -class settings_constraint(MCategory): - ''' - Some parameters that describe a constraint - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_constraint')) - - -class settings_interaction(MCategory): - ''' - Some parameters that describe a bonded interaction. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_interaction')) - - -class soap_parameter(MCategory): - ''' - A soap parameter - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='soap_parameter')) - - -class response_context(MSection): - ''' - The top level context containing the reponse to an api query, when using jsonAPI they - are tipically in the meta part - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='response_context')) - - shortened_meta_info = Quantity( - type=str, - shape=[], - description=''' - A meta info whose corresponding data has been shortened - ''', - a_legacy=LegacyDefinition(name='shortened_meta_info')) - - section_response_message = SubSection( - sub_section=SectionProxy('section_response_message'), - repeats=True, - a_legacy=LegacyDefinition(name='section_response_message')) - - -class section_atom_type(MSection): - ''' - Section describing a type of atom in the system. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_atom_type')) - - atom_type_charge = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='coulomb', - description=''' - Charge of the atom type. - ''', - a_legacy=LegacyDefinition(name='atom_type_charge')) - - atom_type_mass = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='kilogram', - description=''' - Mass of the atom type. - ''', - a_legacy=LegacyDefinition(name='atom_type_mass')) - - atom_type_name = Quantity( - type=str, - shape=[], - description=''' - Name (label) of the atom type. - ''', - a_legacy=LegacyDefinition(name='atom_type_name')) - - -class section_constraint(MSection): - ''' - Section describing a constraint between arbitrary atoms. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_constraint')) - - constraint_atoms = Quantity( - type=np.dtype(np.int32), - shape=['number_of_constraints', 'number_of_atoms_per_constraint'], - description=''' - List of the indexes involved in this constraint. The fist atom has index 1, the - last number_of_topology_atoms. - ''', - a_legacy=LegacyDefinition(name='constraint_atoms')) - - constraint_kind = Quantity( - type=str, - shape=[], - description=''' - Short and unique name for this constraint type. Valid names are described in the - [constraint\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/constraint-kind). - ''', - a_legacy=LegacyDefinition(name='constraint_kind')) - - constraint_parameters = Quantity( - type=typing.Any, - shape=[], - description=''' - Explicit constraint parameters for this kind of constraint (depending on the - constraint type, some might be given implicitly through other means). - ''', - a_legacy=LegacyDefinition(name='constraint_parameters')) - - number_of_atoms_per_constraint = Quantity( - type=int, - shape=[], - description=''' - Number of atoms involved in this constraint. - ''', - a_legacy=LegacyDefinition(name='number_of_atoms_per_constraint')) - - number_of_constraints = Quantity( - type=int, - shape=[], - description=''' - Number of constraints of this type. - ''', - a_legacy=LegacyDefinition(name='number_of_constraints')) - - -class section_dft_plus_u_orbital(MSection): - ''' - Section for DFT+U-settings of a single orbital - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_dft_plus_u_orbital')) - - dft_plus_u_orbital_atom = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - DFT+U-orbital setting: atom index (references index of atom_labels/atom_positions) - ''', - a_legacy=LegacyDefinition(name='dft_plus_u_orbital_atom')) - - dft_plus_u_orbital_J = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - DFT+U-orbital setting: value J (exchange interaction) - ''', - categories=[public.energy_value], - a_legacy=LegacyDefinition(name='dft_plus_u_orbital_J')) - - dft_plus_u_orbital_label = Quantity( - type=str, - shape=[], - description=''' - DFT+U-orbital setting: orbital label (normally (n,l)), notation: '3d', '4f', ... - ''', - a_legacy=LegacyDefinition(name='dft_plus_u_orbital_label')) - - dft_plus_u_orbital_U_effective = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - DFT+U-orbital setting: value U_{effective} (U-J), if implementation uses it - ''', - categories=[public.energy_value], - a_legacy=LegacyDefinition(name='dft_plus_u_orbital_U_effective')) - - dft_plus_u_orbital_U = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - DFT+U-orbital setting: value U (on-site Coulomb interaction) - ''', - categories=[public.energy_value], - a_legacy=LegacyDefinition(name='dft_plus_u_orbital_U')) - - -class section_excited_states(MSection): - ''' - Excited states properties. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_excited_states')) - - excitation_energies = Quantity( - type=np.dtype(np.float64), - shape=['number_of_excited_states'], - description=''' - Excitation energies. - ''', - categories=[public.energy_value], - a_legacy=LegacyDefinition(name='excitation_energies')) - - number_of_excited_states = Quantity( - type=int, - shape=[], - description=''' - Number of excited states. - ''', - a_legacy=LegacyDefinition(name='number_of_excited_states')) - - oscillator_strengths = Quantity( - type=np.dtype(np.float64), - shape=['number_of_excited_states'], - description=''' - Excited states oscillator strengths. - ''', - a_legacy=LegacyDefinition(name='oscillator_strengths')) - - transition_dipole_moments = Quantity( - type=np.dtype(np.float64), - shape=['number_of_excited_states', 3], - description=''' - Transition dipole moments. - ''', - a_legacy=LegacyDefinition(name='transition_dipole_moments')) - - -class section_interaction(MSection): - ''' - Section containing the description of a bonded interaction between arbitrary atoms. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_interaction')) - - interaction_atoms = Quantity( - type=np.dtype(np.int32), - shape=['number_of_interactions', 'number_of_atoms_per_interaction'], - description=''' - List of the indexes involved in this interaction. The fist atom has index 1, the - last atom index number_of_topology_atoms. - ''', - a_legacy=LegacyDefinition(name='interaction_atoms')) - - interaction_kind = Quantity( - type=str, - shape=[], - description=''' - Short and unique name for this interaction type. Valid names are described in the - [interaction\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/interaction-kind). - ''', - a_legacy=LegacyDefinition(name='interaction_kind')) - - interaction_parameters = Quantity( - type=typing.Any, - shape=[], - description=''' - Explicit interaction parameters for this kind of interaction (depending on the - interaction_kind some might be given implicitly through other means). - ''', - a_legacy=LegacyDefinition(name='interaction_parameters')) - - number_of_atoms_per_interaction = Quantity( - type=int, - shape=[], - description=''' - Number of atoms involved in this interaction. - ''', - a_legacy=LegacyDefinition(name='number_of_atoms_per_interaction')) - - number_of_interactions = Quantity( - type=int, - shape=[], - description=''' - Number of interactions of this type. - ''', - a_legacy=LegacyDefinition(name='number_of_interactions')) - - -class section_method_basis_set(MSection): - ''' - This section contains the definition of the basis sets that are defined independently - of the atomic configuration. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_method_basis_set')) - - mapping_section_method_basis_set_atom_centered = Quantity( - type=np.dtype(np.int64), - shape=['number_of_basis_sets_atom_centered', 2], - description=''' - Reference to an atom-centered basis set defined in section_basis_set_atom_centered - and to the atom kind as defined in section_method_atom_kind. - ''', - a_legacy=LegacyDefinition(name='mapping_section_method_basis_set_atom_centered')) - - mapping_section_method_basis_set_cell_associated = Quantity( - type=public.section_basis_set_cell_dependent, - shape=[], - description=''' - Reference to a cell-associated basis set. - ''', - a_legacy=LegacyDefinition(name='mapping_section_method_basis_set_cell_associated')) - - method_basis_set_kind = Quantity( - type=str, - shape=[], - description=''' - String describing the use of the basis set, i.e, if it used for expanding a - wavefunction or an electron density. Allowed values are listed in the - [basis\\_set\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/basis-set-kind). - ''', - a_legacy=LegacyDefinition(name='method_basis_set_kind')) - - number_of_basis_sets_atom_centered = Quantity( - type=int, - shape=[], - description=''' - String describing the use of the basis set, i.e, if it used for expanding a - wavefunction or an electron density. Allowed values are listed in the - [basis\\_set\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/basis-set-kind). - ''', - a_legacy=LegacyDefinition(name='number_of_basis_sets_atom_centered')) - - -class section_molecule_constraint(MSection): - ''' - Section describing a constraint between atoms within a molecule. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_molecule_constraint')) - - molecule_constraint_atoms = Quantity( - type=np.dtype(np.int32), - shape=['number_of_molecule_constraints', 'number_of_atoms_per_molecule_constraint'], - description=''' - List of the indexes involved in this constraint. The fist atom has index 1, the - last index is number_of_atoms_in_molecule. - ''', - a_legacy=LegacyDefinition(name='molecule_constraint_atoms')) - - molecule_constraint_kind = Quantity( - type=str, - shape=[], - description=''' - Short and unique name for this constraint type. Valid names are described in the - [constraint\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/constraint-kind). - ''', - a_legacy=LegacyDefinition(name='molecule_constraint_kind')) - - molecule_constraint_parameters = Quantity( - type=typing.Any, - shape=[], - description=''' - Explicit constraint parameters for this kind of constraint (depending on the - constraint type some might be given implicitly through other means). - ''', - a_legacy=LegacyDefinition(name='molecule_constraint_parameters')) - - number_of_atoms_per_molecule_constraint = Quantity( - type=int, - shape=[], - description=''' - Number of atoms, in this molecule, involved in this constraint. - ''', - a_legacy=LegacyDefinition(name='number_of_atoms_per_molecule_constraint')) - - number_of_molecule_constraints = Quantity( - type=int, - shape=[], - description=''' - Number of constraints of this type. - ''', - a_legacy=LegacyDefinition(name='number_of_molecule_constraints')) - - -class section_molecule_interaction(MSection): - ''' - Section describing a bonded interaction between atoms within a molecule. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_molecule_interaction')) - - molecule_interaction_atoms = Quantity( - type=np.dtype(np.int32), - shape=['number_of_molecule_interactions', 'number_of_atoms_per_molecule_interaction'], - description=''' - List of the indexes involved in this bonded interaction within a molecule. The - first atom has index 1, the last index is number_of_atoms_in_. - ''', - a_legacy=LegacyDefinition(name='molecule_interaction_atoms')) - - molecule_interaction_kind = Quantity( - type=str, - shape=[], - description=''' - Short and unique name for this interaction type, used for bonded interactions for - atoms in a molecule. Valid names are described in the [interaction\\_kind wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/interaction-kind). - ''', - a_legacy=LegacyDefinition(name='molecule_interaction_kind')) - - molecule_interaction_parameters = Quantity( - type=typing.Any, - shape=[], - description=''' - Explicit interaction parameters for this kind of interaction (depending on the - interaction type some might be given implicitly through other means), used for - bonded interactions for atoms in a molecule. - ''', - a_legacy=LegacyDefinition(name='molecule_interaction_parameters')) - - number_of_atoms_per_molecule_interaction = Quantity( - type=int, - shape=[], - description=''' - Number of atoms, in this molecule, involved in this interaction. - ''', - a_legacy=LegacyDefinition(name='number_of_atoms_per_molecule_interaction')) - - number_of_molecule_interactions = Quantity( - type=int, - shape=[], - description=''' - Number of bonded interactions of this type. - ''', - a_legacy=LegacyDefinition(name='number_of_molecule_interactions')) - - -class section_molecule_type(MSection): - ''' - Section describing a type of molecule in the system. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_molecule_type')) - - atom_in_molecule_charge = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms_in_molecule'], - unit='coulomb', - description=''' - Charge of each atom in the molecule. - ''', - categories=[settings_atom_in_molecule], - a_legacy=LegacyDefinition(name='atom_in_molecule_charge')) - - atom_in_molecule_name = Quantity( - type=str, - shape=['number_of_atoms_in_molecule'], - description=''' - Name (label) of each atom in the molecule. - ''', - categories=[settings_atom_in_molecule], - a_legacy=LegacyDefinition(name='atom_in_molecule_name')) - - atom_in_molecule_to_atom_type_ref = Quantity( - type=Reference(SectionProxy('section_atom_type')), - shape=['number_of_atoms_in_molecule'], - description=''' - Reference to the atom type of each atom in the molecule. - ''', - categories=[settings_atom_in_molecule], - a_legacy=LegacyDefinition(name='atom_in_molecule_to_atom_type_ref')) - - molecule_type_name = Quantity( - type=str, - shape=[], - description=''' - Name of the molecule. - ''', - a_legacy=LegacyDefinition(name='molecule_type_name')) - - number_of_atoms_in_molecule = Quantity( - type=int, - shape=[], - description=''' - Number of atoms in this molecule. - ''', - a_legacy=LegacyDefinition(name='number_of_atoms_in_molecule')) - - section_molecule_constraint = SubSection( - sub_section=SectionProxy('section_molecule_constraint'), - repeats=True, - a_legacy=LegacyDefinition(name='section_molecule_constraint')) - - section_molecule_interaction = SubSection( - sub_section=SectionProxy('section_molecule_interaction'), - repeats=True, - a_legacy=LegacyDefinition(name='section_molecule_interaction')) - - -class section_response_message(MSection): - ''' - Messages outputted by the program formatting the data in the current response - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_response_message')) - - response_message_count = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - How many times this message was repeated - ''', - a_legacy=LegacyDefinition(name='response_message_count')) - - response_message_level = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - level of the message: 0 fatal, 1 error, 2 warning, 3 debug - ''', - a_legacy=LegacyDefinition(name='response_message_level')) - - response_message = Quantity( - type=str, - shape=[], - description=''' - Message outputted by the program formatting the data in the current format - ''', - a_legacy=LegacyDefinition(name='response_message')) - - -class section_soap_coefficients(MSection): - ''' - Stores the soap coefficients for the pair of atoms given in - soap_coefficients_atom_pair. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_soap_coefficients')) - - number_of_soap_coefficients = Quantity( - type=int, - shape=[], - description=''' - number of soap coefficients - ''', - a_legacy=LegacyDefinition(name='number_of_soap_coefficients')) - - soap_coefficients_atom_pair = Quantity( - type=str, - shape=[], - description=''' - Pair of atoms described in the current section - ''', - a_legacy=LegacyDefinition(name='soap_coefficients_atom_pair')) - - soap_coefficients = Quantity( - type=np.dtype(np.float64), - shape=['number_of_soap_coefficients'], - description=''' - Compressed coefficient of the soap descriptor for the atom pair - soap_coefficients_atom_pair - ''', - a_legacy=LegacyDefinition(name='soap_coefficients')) - - -class section_soap(MSection): - ''' - Stores a soap descriptor for this configuration. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_soap')) - - soap_angular_basis_L = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - angular basis L - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_angular_basis_L')) - - soap_angular_basis_type = Quantity( - type=str, - shape=[], - description=''' - angular basis type - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_angular_basis_type')) - - soap_kernel_adaptor = Quantity( - type=str, - shape=[], - description=''' - kernel adaptor - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_kernel_adaptor')) - - soap_parameters_gid = Quantity( - type=str, - shape=[], - description=''' - Unique checksum of all the soap parameters (all those with abstract type - soap_parameter) with prefix psoap - ''', - a_legacy=LegacyDefinition(name='soap_parameters_gid')) - - soap_radial_basis_integration_steps = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - radial basis integration steps - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_radial_basis_integration_steps')) - - soap_radial_basis_mode = Quantity( - type=str, - shape=[], - description=''' - radial basis mode - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_radial_basis_mode')) - - soap_radial_basis_n = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - radial basis N - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_radial_basis_n')) - - soap_radial_basis_sigma = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - radial basis sigma - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_radial_basis_sigma')) - - soap_radial_basis_type = Quantity( - type=str, - shape=[], - description=''' - radial basis type - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_radial_basis_type')) - - soap_radial_cutoff_center_weight = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - radial cutoff center weight - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_radial_cutoff_center_weight')) - - soap_radial_cutoff_rc_width = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - radial cutoff width - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_radial_cutoff_rc_width')) - - soap_radial_cutoff_rc = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - radial cutoff - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_radial_cutoff_rc')) - - soap_radial_cutoff_type = Quantity( - type=str, - shape=[], - description=''' - radial cutoff type - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_radial_cutoff_type')) - - soap_spectrum_2l1_norm = Quantity( - type=bool, - shape=[], - description=''' - 2l1 norm spectrum - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_spectrum_2l1_norm')) - - soap_spectrum_global = Quantity( - type=bool, - shape=[], - description=''' - global spectrum - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_spectrum_global')) - - soap_spectrum_gradients = Quantity( - type=bool, - shape=[], - description=''' - gradients in specturm - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_spectrum_gradients')) - - soap_type_list = Quantity( - type=str, - shape=[], - description=''' - Type list - ''', - categories=[soap_parameter], - a_legacy=LegacyDefinition(name='soap_type_list')) - - section_soap_coefficients = SubSection( - sub_section=SectionProxy('section_soap_coefficients'), - repeats=True, - a_legacy=LegacyDefinition(name='section_soap_coefficients')) - - -class section_topology(MSection): - ''' - Section containing the definition of topology (connectivity among atoms in force - fileds), force field, and constraints of a system. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_topology')) - - atom_to_molecule = Quantity( - type=np.dtype(np.int32), - shape=['number_of_topology_atoms', 2], - description=''' - Table mapping atom to molecules: the first column is the index of the molecule and - the second column the index of the atom, signifying that the atom in the second - column belongs to the molecule in the first column in the same row. - ''', - a_legacy=LegacyDefinition(name='atom_to_molecule')) - - molecule_to_molecule_type_map = Quantity( - type=Reference(SectionProxy('section_molecule_type')), - shape=['number_of_topology_molecules'], - description=''' - Mapping from molecules to molecule types. - ''', - a_legacy=LegacyDefinition(name='molecule_to_molecule_type_map')) - - number_of_topology_atoms = Quantity( - type=int, - shape=[], - description=''' - Number of atoms in the system described by this topology. - ''', - a_legacy=LegacyDefinition(name='number_of_topology_atoms')) - - number_of_topology_molecules = Quantity( - type=int, - shape=[], - description=''' - Number of molecules in the system, as described by this topology. - ''', - a_legacy=LegacyDefinition(name='number_of_topology_molecules')) - - topology_force_field_name = Quantity( - type=str, - shape=[], - description=''' - A unique string idenfiying the force field defined in this section. Strategies to - define it are discussed in the - [topology\\_force\\_field\\_name](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/topology-force-field-name). - ''', - a_legacy=LegacyDefinition(name='topology_force_field_name')) - - section_atom_type = SubSection( - sub_section=SectionProxy('section_atom_type'), - repeats=True, - a_legacy=LegacyDefinition(name='section_atom_type')) - - section_constraint = SubSection( - sub_section=SectionProxy('section_constraint'), - repeats=True, - a_legacy=LegacyDefinition(name='section_constraint')) - - section_interaction = SubSection( - sub_section=SectionProxy('section_interaction'), - repeats=True, - a_legacy=LegacyDefinition(name='section_interaction')) - - section_molecule_type = SubSection( - sub_section=SectionProxy('section_molecule_type'), - repeats=True, - a_legacy=LegacyDefinition(name='section_molecule_type')) - - -class section_method(public.section_method): - - m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_method')) - - dft_plus_u_functional = Quantity( - type=str, - shape=[], - description=''' - Type of DFT+U functional (such as DFT/DFT+U double-counting compensation). Valid - names are described in the [dft\\_plus\\_u\\_functional wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/dft- - plus-u-functional). - ''', - a_legacy=LegacyDefinition(name='dft_plus_u_functional')) - - dft_plus_u_projection_type = Quantity( - type=str, - shape=[], - description=''' - DFT+U: Type of orbitals used for projection in order to calculate occupation - numbers. Valid names are described in the [dft\\_plus\\_u\\_projection\\_type wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/dft- - plus-u-projection-type). - ''', - a_legacy=LegacyDefinition(name='dft_plus_u_projection_type')) - - gw_bare_coulomb_cutofftype = Quantity( - type=str, - shape=[], - description=''' - Cutoff type for the calculation of the bare Coulomb potential: none, 0d, 1d, 2d. - See Rozzi et al., PRB 73, 205119 (2006) - ''', - a_legacy=LegacyDefinition(name='gw_bare_coulomb_cutofftype')) - - gw_bare_coulomb_gmax = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='1 / meter', - description=''' - Maximum G for the pw basis for the Coulomb potential. - ''', - a_legacy=LegacyDefinition(name='gw_bare_coulomb_gmax')) - - gw_basis_set = Quantity( - type=str, - shape=[], - description=''' - Auxillary basis set used for non-local operators: mixed - mixed basis set, Kotani - and Schilfgaarde, Solid State Comm. 121, 461 (2002). - ''', - a_legacy=LegacyDefinition(name='gw_basis_set')) - - gw_core_treatment = Quantity( - type=str, - shape=[], - description=''' - It specifies whether the core states are treated in the GW calculation: all - All - electron calculation; val - Valence electron only calculation; vab - Core - electrons are excluded from the mixed product basis; xal - All electron treatment - of the exchange self-energy only - ''', - a_legacy=LegacyDefinition(name='gw_core_treatment')) - - gw_frequency_grid_type = Quantity( - type=str, - shape=[], - description=''' - Frequency integration grid type for the correlational self energy: 'eqdis' - - equidistant frequencies from 0 to freqmax; 'gaulag' - Gauss-Laguerre quadrature - from 0 to infinity; 'gauleg' - Gauss-Legendre quadrature from 0 to freqmax; - 'gaule2' (default) - double Gauss-Legendre quadrature from 0 to freqmax and from - freqmax to infinity. - ''', - a_legacy=LegacyDefinition(name='gw_frequency_grid_type')) - - gw_max_frequency = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Maximum frequency for the calculation of the self energy. - ''', - a_legacy=LegacyDefinition(name='gw_max_frequency')) - - gw_mixed_basis_gmax = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='1 / meter', - description=''' - Cut-off parameter for the truncation of the expansion of the plane waves in the - interstitial region. - ''', - a_legacy=LegacyDefinition(name='gw_mixed_basis_gmax')) - - gw_mixed_basis_lmax = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - Maximum l value used for the radial functions within the muffin-tin. - ''', - a_legacy=LegacyDefinition(name='gw_mixed_basis_lmax')) - - gw_mixed_basis_tolerance = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Eigenvalue threshold below which the egenvectors are discarded in the construction - of the radial basis set. - ''', - a_legacy=LegacyDefinition(name='gw_mixed_basis_tolerance')) - - gw_ngridq = Quantity( - type=np.dtype(np.int32), - shape=[3], - description=''' - k/q-point grid size used in the GW calculation. - ''', - a_legacy=LegacyDefinition(name='gw_ngridq')) - - gw_frequency_number = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - Number referring to the frequency used in the calculation of the self energy. - ''', - a_legacy=LegacyDefinition(name='gw_frequency_number')) - - gw_frequency_values = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Values of the frequency used in the calculation of the self energy. - ''', - a_legacy=LegacyDefinition(name='gw_frequency_values')) - - gw_frequency_weights = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Weights of the frequency used in the calculation of the self energy. - ''', - a_legacy=LegacyDefinition(name='gw_frequency_weights')) - - gw_number_of_frequencies = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - Number of frequency points used in the calculation of the self energy. - ''', - a_legacy=LegacyDefinition(name='gw_number_of_frequencies')) - - gw_polarizability_number_of_empty_states = Quantity( - type=int, - shape=[], - description=''' - Number of empty states used to compute the polarizability P - ''', - a_legacy=LegacyDefinition(name='gw_polarizability_number_of_empty_states')) - - gw_qp_equation_treatment = Quantity( - type=str, - shape=[], - description=''' - Methods to solve the quasi-particle equation: 'linearization', 'self-consistent' - ''', - a_legacy=LegacyDefinition(name='gw_qp_equation_treatment')) - - gw_screened_coulomb_volume_average = Quantity( - type=str, - shape=[], - description=''' - Type of volume averaging for the dynamically screened Coulomb potential: isotropic - - Simple averaging along a specified direction using only diagonal components of - the dielectric tensor; anisotropic - Anisotropic screening by C. Freysoldt et al., - CPC 176, 1-13 (2007) - ''', - a_legacy=LegacyDefinition(name='gw_screened_coulomb_volume_average')) - - gw_screened_Coulomb = Quantity( - type=str, - shape=[], - description=''' - Model used to calculate the dinamically-screened Coulomb potential: 'rpa' - Full- - frequency random-phase approximation; 'ppm' - Godby-Needs plasmon-pole model Godby - and Needs, Phys. Rev. Lett. 62, 1169 (1989); 'ppm_hl' - Hybertsen and Louie, Phys. - Rev. B 34, 5390 (1986); 'ppm_lh' - von der Linden and P. Horsh, Phys. Rev. B 37, - 8351 (1988); 'ppm_fe' - Farid and Engel, Phys. Rev. B 47,15931 (1993); 'cdm' - - Contour deformation method, Phys. Rev. B 67, 155208 (2003).) - ''', - a_legacy=LegacyDefinition(name='gw_screened_Coulomb')) - - gw_self_energy_c_analytical_continuation = Quantity( - type=str, - shape=[], - description=''' - Models for the correlation self-energy analytical continuation: 'pade' - Pade's - approximant (by H. J. Vidberg and J. W. Serence, J. Low Temp. Phys. 29, 179 - (1977)); 'mpf' - Multi-Pole Fitting (by H. N Rojas, R. W. Godby and R. J. Needs, - Phys. Rev. Lett. 74, 1827 (1995)); 'cd' - contour deformation; 'ra' - real axis - ''', - a_legacy=LegacyDefinition(name='gw_self_energy_c_analytical_continuation')) - - gw_self_energy_c_number_of_empty_states = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - Number of empty states to be used to calculate the correlation self energy. - ''', - a_legacy=LegacyDefinition(name='gw_self_energy_c_number_of_empty_states')) - - gw_self_energy_c_number_of_poles = Quantity( - type=int, - shape=[], - description=''' - Number of poles used in the analytical continuation. - ''', - a_legacy=LegacyDefinition(name='gw_self_energy_c_number_of_poles')) - - gw_self_energy_singularity_treatment = Quantity( - type=str, - shape=[], - description=''' - Treatment of the integrable singular terms in the calculation of the self energy. - Values: 'mpb' - Auxiliary function method by S. Massidda, M. Posternak, and A. - Baldereschi, PRB 48, 5058 (1993); 'crg' - Auxiliary function method by P. Carrier, - S. Rohra, and A. Goerling, PRB 75, 205126 (2007). - ''', - a_legacy=LegacyDefinition(name='gw_self_energy_singularity_treatment')) - - gw_starting_point = Quantity( - type=str, - shape=[], - description=''' - Exchange-correlation functional of the ground-state calculation. See XC_functional - list at https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- - functional - ''', - a_legacy=LegacyDefinition(name='gw_starting_point')) - - gw_type_test = Quantity( - type=str, - shape=[], - description=''' - GW methodology: exciting test variable - ''', - a_legacy=LegacyDefinition(name='gw_type_test')) - - gw_type = Quantity( - type=str, - shape=[], - description=''' - GW methodology: G0W0; ev-scGW: (eigenvalues self-consistent GW) – Phys.Rev.B 34, - 5390 (1986); qp-scGW: (quasi-particle self-consistent GW) – Phys. Rev. Lett. 96, - 226402 (2006) scGW0: (self-consistent G with fixed W0) – Phys.Rev.B 54, 8411 - (1996); scG0W: (self-consistent W with fixed G0); scGW: (self-consistent GW) – - Phys. Rev. B 88, 075105 (2013) - ''', - a_legacy=LegacyDefinition(name='gw_type')) - - method_to_topology_ref = Quantity( - type=Reference(SectionProxy('section_topology')), - shape=[], - description=''' - Reference to the topology and force fields to be used. - ''', - a_legacy=LegacyDefinition(name='method_to_topology_ref')) - - section_dft_plus_u_orbital = SubSection( - sub_section=SectionProxy('section_dft_plus_u_orbital'), - repeats=True, - a_legacy=LegacyDefinition(name='section_dft_plus_u_orbital')) - - section_method_basis_set = SubSection( - sub_section=SectionProxy('section_method_basis_set'), - repeats=True, - a_legacy=LegacyDefinition(name='section_method_basis_set')) - - -class section_single_configuration_calculation(public.section_single_configuration_calculation): - - m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_single_configuration_calculation')) - - energy_C_mGGA = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Component of the correlation (C) energy at the GGA (or MetaGGA) level using the - self-consistent density of the target XC functional (full unscaled value, i.e., - not scaled due to exact-exchange mixing). - ''', - categories=[public.energy_component, public.energy_value, public.energy_type_C], - a_legacy=LegacyDefinition(name='energy_C_mGGA')) - - energy_reference_fermi = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels'], - unit='joule', - description=''' - Fermi energy (separates occupied from unoccupied single-particle states in metals) - ''', - categories=[public.energy_type_reference, public.energy_value], - a_legacy=LegacyDefinition(name='energy_reference_fermi')) - - energy_reference_highest_occupied = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels'], - unit='joule', - description=''' - Highest occupied single-particle state energy (in insulators or HOMO energy in - finite systems) - ''', - categories=[public.energy_type_reference, public.energy_value], - a_legacy=LegacyDefinition(name='energy_reference_highest_occupied')) - - energy_reference_lowest_unoccupied = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels'], - unit='joule', - description=''' - Lowest unoccupied single-particle state energy (in insulators or LUMO energy in - finite systems) - ''', - categories=[public.energy_type_reference, public.energy_value], - a_legacy=LegacyDefinition(name='energy_reference_lowest_unoccupied')) - - energy_X_mGGA_scaled = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Component of the exchange (X) energy at the GGA (or MetaGGA) level, using the self - consistent density of the target functional, scaled accordingly to the mixing - parameter. - ''', - categories=[public.energy_component, public.energy_value], - a_legacy=LegacyDefinition(name='energy_X_mGGA_scaled')) - - energy_X_mGGA = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Component of the exchange (X) energy at the GGA (or MetaGGA) level using the self - consistent density of the target functional (full unscaled value, i.e., not scaled - due to exact-exchange mixing). - ''', - categories=[public.energy_type_X, public.energy_component, public.energy_value], - a_legacy=LegacyDefinition(name='energy_X_mGGA')) - - gw_fermi_energy = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - GW Fermi energy - ''', - a_legacy=LegacyDefinition(name='gw_fermi_energy')) - - gw_fundamental_gap = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - GW fundamental band gap - ''', - a_legacy=LegacyDefinition(name='gw_fundamental_gap')) - - gw_optical_gap = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - GW optical band gap - ''', - a_legacy=LegacyDefinition(name='gw_optical_gap')) - - gw_self_energy_c = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], - unit='joule', - description=''' - Diagonal matrix elements of the correlation self-energy - ''', - a_legacy=LegacyDefinition(name='gw_self_energy_c')) - - gw_self_energy_x = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], - unit='joule', - description=''' - Diagonal matrix elements of the exchange self-energy - ''', - a_legacy=LegacyDefinition(name='gw_self_energy_x')) - - gw_xc_potential = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], - unit='joule', - description=''' - Diagonal matrix elements of the exchange-correlation potential - ''', - a_legacy=LegacyDefinition(name='gw_xc_potential')) - - section_excited_states = SubSection( - sub_section=SectionProxy('section_excited_states'), - repeats=True, - a_legacy=LegacyDefinition(name='section_excited_states')) - - -class section_scf_iteration(public.section_scf_iteration): - - m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_scf_iteration')) - - energy_reference_fermi_iteration = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels'], - unit='joule', - description=''' - Fermi energy (separates occupied from unoccupied single-particle states in metals) - during the self-consistent field (SCF) iterations. - ''', - categories=[public.energy_type_reference, public.energy_value], - a_legacy=LegacyDefinition(name='energy_reference_fermi_iteration')) - - energy_reference_highest_occupied_iteration = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels'], - unit='joule', - description=''' - Highest occupied single-particle state energy (in insulators or HOMO energy in - finite systems) during the self-consistent field (SCF) iterations. - ''', - categories=[public.energy_type_reference, public.energy_value], - a_legacy=LegacyDefinition(name='energy_reference_highest_occupied_iteration')) - - energy_reference_lowest_unoccupied_iteration = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels'], - unit='joule', - description=''' - Lowest unoccupied single-particle state energy (in insulators or LUMO energy in - finite systems) during the self-consistent field (SCF) iterations. - ''', - categories=[public.energy_type_reference, public.energy_value], - a_legacy=LegacyDefinition(name='energy_reference_lowest_unoccupied_iteration')) - - -class section_eigenvalues(public.section_eigenvalues): - - m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_eigenvalues')) - - gw_qp_linearization_prefactor = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], - description=''' - Linearization prefactor - ''', - a_legacy=LegacyDefinition(name='gw_qp_linearization_prefactor')) - - -class section_system(public.section_system): - - m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_system')) - - number_of_electrons = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels'], - description=''' - Number of electrons in system - ''', - categories=[public.configuration_core], - a_legacy=LegacyDefinition(name='number_of_electrons')) - - topology_ref = Quantity( - type=Reference(SectionProxy('section_topology')), - shape=[], - description=''' - Reference to the topology used for this system; if not given, the trivial topology - should be assumed. - ''', - a_legacy=LegacyDefinition(name='topology_ref')) - - is_representative = Quantity( - type=bool, - shape=[], - description=''' - Most systems in a run are only minor variations of each other. Systems marked - representative where chosen to be representative for all systems in the run. - ''', - a_legacy=LegacyDefinition(name='is_representative')) - - section_soap = SubSection( - sub_section=SectionProxy('section_soap'), - repeats=True, - a_legacy=LegacyDefinition(name='section_soap')) - - -class section_run(public.section_run): - - m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_run')) - - section_topology = SubSection( - sub_section=SectionProxy('section_topology'), - repeats=True, - a_legacy=LegacyDefinition(name='section_topology')) - - -m_package.__init_metainfo__() +m_package = Package(name='common_nomadmetainfo_json') diff --git a/nomad/datamodel/metainfo/common_dft.py b/nomad/datamodel/metainfo/common_dft.py new file mode 100644 index 0000000000000000000000000000000000000000..a93a7966117ba5b626a1f3d5f9f429cc1f41aeb8 --- /dev/null +++ b/nomad/datamodel/metainfo/common_dft.py @@ -0,0 +1,7784 @@ +import numpy as np # pylint: disable=unused-import +import typing # pylint: disable=unused-import +from nomad.metainfo import ( # pylint: disable=unused-import + MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy, + Reference, MEnum, derived) +from nomad.metainfo.legacy import LegacyDefinition +from nomad.metainfo.search_extension import Search + + +m_package = Package( + name='nomad.datamodel.metainfo.public_old', + description='None', + a_legacy=LegacyDefinition(name='public.nomadmetainfo.json')) + + +class FastAccess(MCategory): + ''' + Used to mark archive objects that need to be stored in a fast 2nd-tier storage medium, + because they are frequently accessed via archive API. + + If applied to a sub_section, the section will be added to the fast storage. Currently + this only works for *root* sections that are sub_sections of `EntryArchive`. + + If applied to a reference types quantity, the referenced section will also be added to + the fast storage, regardless if the referenced section has the category or not. + ''' + + m_def = Category( + aliases=['fast_access'],) + + +class AccessoryInfo(MCategory): + ''' + Information that *in theory* should not affect the results of the calculations (e.g., + timing). + ''' + + m_def = Category( + aliases=['accessory_info'], + a_legacy=LegacyDefinition(name='accessory_info')) + + +class AtomForcesType(MCategory): + ''' + The types of forces acting on the atoms (i.e., minus derivatives of the specific type + of energy with respect to the atom position). + ''' + + m_def = Category( + aliases=['atom_forces_type'], + a_legacy=LegacyDefinition(name='atom_forces_type')) + + +class BasisSetDescription(MCategory): + ''' + One of the parts building the basis set of the system (e.g., some atom-centered basis + set, plane-waves or both). + ''' + + m_def = Category( + aliases=['basis_set_description'], + a_legacy=LegacyDefinition(name='basis_set_description')) + + +class ConfigurationCore(MCategory): + ''' + Properties defining the current configuration. + ''' + + m_def = Category( + aliases=['configuration_core'], + a_legacy=LegacyDefinition(name='configuration_core')) + + +class ConservedQuantity(MCategory): + ''' + A quantity that is preserved during the time propagation (for example, + kinetic+potential energy during NVE). + ''' + + m_def = Category( + aliases=['conserved_quantity'], + a_legacy=LegacyDefinition(name='conserved_quantity')) + + +class EnergyValue(MCategory): + ''' + This metadata stores an energy value. + ''' + + m_def = Category( + aliases=['energy_value'], + a_legacy=LegacyDefinition(name='energy_value')) + + +class ErrorEstimateContribution(MCategory): + ''' + An estimate of a partial quantity contributing to the error for a given quantity. + ''' + + m_def = Category( + aliases=['error_estimate_contribution'], + a_legacy=LegacyDefinition(name='error_estimate_contribution')) + + +class MessageDebug(MCategory): + ''' + A debugging message of the computational program. + ''' + + m_def = Category( + aliases=['message_debug'], + a_legacy=LegacyDefinition(name='message_debug')) + + +class ParsingMessageDebug(MCategory): + ''' + This field is used for debugging messages of the parsing program. + ''' + + m_def = Category( + aliases=['parsing_message_debug'], + a_legacy=LegacyDefinition(name='parsing_message_debug')) + + +class ScfInfo(MCategory): + ''' + Contains information on the self-consistent field (SCF) procedure, i.e. the number of + SCF iterations (number_of_scf_iterations) or a section_scf_iteration section with + detailed information on the SCF procedure of specified quantities. + ''' + + m_def = Category( + aliases=['scf_info'], + a_legacy=LegacyDefinition(name='scf_info')) + + +class SettingsNumericalParameter(MCategory): + ''' + A parameter that can influence the convergence, but not the physics (unlike + settings_physical_parameter) + ''' + + m_def = Category( + aliases=['settings_numerical_parameter'], + a_legacy=LegacyDefinition(name='settings_numerical_parameter')) + + +class SettingsPhysicalParameter(MCategory): + ''' + A parameter that defines the physical model used. Use settings_numerical_parameter for + parameters that that influence only the convergence/accuracy. + ''' + + m_def = Category( + aliases=['settings_physical_parameter'], + a_legacy=LegacyDefinition(name='settings_physical_parameter')) + + +class SettingsPotentialEnergySurface(MCategory): + ''' + Contains parameters that control the potential energy surface. + ''' + + m_def = Category( + aliases=['settings_potential_energy_surface'], + a_legacy=LegacyDefinition(name='settings_potential_energy_surface')) + + +class SettingsRun(MCategory): + ''' + Contains parameters that control the whole run (but not the *single configuration + calculation*, see section_single_configuration_calculation). + ''' + + m_def = Category( + aliases=['settings_run'], + a_legacy=LegacyDefinition(name='settings_run')) + + +class SettingsSampling(MCategory): + ''' + Contains parameters controlling the sampling. + ''' + + m_def = Category( + aliases=['settings_sampling'], + a_legacy=LegacyDefinition(name='settings_sampling')) + + +class SettingsScf(MCategory): + ''' + Contains parameters connected with the convergence of the self-consistent field (SCF) + iterations. + ''' + + m_def = Category( + aliases=['settings_scf'], + a_legacy=LegacyDefinition(name='settings_scf')) + + +class SettingsSmearing(MCategory): + ''' + Contain parameters that control the smearing of the orbital occupation at finite + electronic temperatures. + ''' + + m_def = Category( + aliases=['settings_smearing'], + a_legacy=LegacyDefinition(name='settings_smearing')) + + +class SettingsStressTensor(MCategory): + ''' + Settings to calculate the stress tensor (stress_tensor) consistent with the total + energy of the system given in energy_total. + ''' + + m_def = Category( + aliases=['settings_stress_tensor'], + a_legacy=LegacyDefinition(name='settings_stress_tensor')) + + +class StressTensorType(MCategory): + ''' + Contains the final value of the default stress tensor (stress_tensor) and/or the value + of the stress tensor (stress_tensor_value) of the kind defined in stress_tensor_kind. + ''' + + m_def = Category( + aliases=['stress_tensor_type'], + a_legacy=LegacyDefinition(name='stress_tensor_type')) + + +class SettingsAtomInMolecule(MCategory): + ''' + Parameters of an atom within a molecule. + ''' + + m_def = Category( + aliases=['settings_atom_in_molecule'], + a_legacy=LegacyDefinition(name='settings_atom_in_molecule')) + + +class SettingsConstraint(MCategory): + ''' + Some parameters that describe a constraint + ''' + + m_def = Category( + aliases=['settings_constraint'], + a_legacy=LegacyDefinition(name='settings_constraint')) + + +class SettingsInteraction(MCategory): + ''' + Some parameters that describe a bonded interaction. + ''' + + m_def = Category( + aliases=['settings_interaction'], + a_legacy=LegacyDefinition(name='settings_interaction')) + + +class SoapParameter(MCategory): + ''' + A soap parameter + ''' + + m_def = Category( + aliases=['soap_parameter'], + a_legacy=LegacyDefinition(name='soap_parameter')) + + +class Unused(MCategory): + ''' + This metainfo definition is not used by NOMAD data. + ''' + + m_def = Category() + + +class EnergyComponentPerAtom(MCategory): + ''' + A value of an energy component per atom, concurring in defining the total energy per + atom. + ''' + + m_def = Category( + aliases=['energy_component_per_atom'], + categories=[EnergyValue], + a_legacy=LegacyDefinition(name='energy_component_per_atom')) + + +class EnergyComponent(MCategory): + ''' + A value of an energy component, expected to be an extensive property. + ''' + + m_def = Category( + aliases=['energy_component'], + categories=[EnergyValue], + a_legacy=LegacyDefinition(name='energy_component')) + + +class EnergyTypeReference(MCategory): + ''' + This metadata stores an energy used as reference point. + ''' + + m_def = Category( + aliases=['energy_type_reference'], + categories=[EnergyValue], + a_legacy=LegacyDefinition(name='energy_type_reference')) + + +class ErrorEstimate(MCategory): + ''' + An estimate of the error on the converged (final) value. + ''' + + m_def = Category( + aliases=['error_estimate'], + categories=[ErrorEstimateContribution], + a_legacy=LegacyDefinition(name='error_estimate')) + + +class MessageInfo(MCategory): + ''' + An information message of the computational program. + ''' + + m_def = Category( + aliases=['message_info'], + categories=[MessageDebug], + a_legacy=LegacyDefinition(name='message_info')) + + +class ParallelizationInfo(MCategory): + ''' + Contains information on the parallelization of the program, i.e. which parallel + programming language was used and its version, how many cores had been working on the + calculation and the flags and parameters needed to run the parallelization of the + code. + ''' + + m_def = Category( + aliases=['parallelization_info'], + categories=[AccessoryInfo], + a_legacy=LegacyDefinition(name='parallelization_info')) + + +class ParsingMessageInfo(MCategory): + ''' + This field is used for info messages of the parsing program. + ''' + + m_def = Category( + aliases=['parsing_message_info'], + categories=[ParsingMessageDebug], + a_legacy=LegacyDefinition(name='parsing_message_info')) + + +class ProgramInfo(MCategory): + ''' + Contains information on the program that generated the data, i.e. the program_name, + program_version, program_compilation_host and program_compilation_datetime as direct + children of this field. + ''' + + m_def = Category( + aliases=['program_info'], + categories=[AccessoryInfo], + a_legacy=LegacyDefinition(name='program_info')) + + +class SettingsGeometryOptimization(MCategory): + ''' + Contains parameters controlling the geometry optimization. + ''' + + m_def = Category( + aliases=['settings_geometry_optimization'], + categories=[SettingsSampling], + a_legacy=LegacyDefinition(name='settings_geometry_optimization')) + + +class SettingsKPoints(MCategory): + ''' + Contains parameters that control the $k$-point mesh. + ''' + + m_def = Category( + aliases=['settings_k_points'], + categories=[SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_k_points')) + + +class SettingsMetadynamics(MCategory): + ''' + Contains parameters that control the metadynamics sampling. + ''' + + m_def = Category( + aliases=['settings_metadynamics'], + categories=[SettingsSampling], + a_legacy=LegacyDefinition(name='settings_metadynamics')) + + +class SettingsMolecularDynamics(MCategory): + ''' + Contains parameters that control the molecular dynamics sampling. + ''' + + m_def = Category( + aliases=['settings_molecular_dynamics'], + categories=[SettingsSampling], + a_legacy=LegacyDefinition(name='settings_molecular_dynamics')) + + +class SettingsMonteCarlo(MCategory): + ''' + Contains parameters that control the Monte-Carlo sampling. + ''' + + m_def = Category( + aliases=['settings_Monte_Carlo'], + categories=[SettingsSampling], + a_legacy=LegacyDefinition(name='settings_Monte_Carlo')) + + +class SettingsXC(MCategory): + ''' + Contains parameters connected with the definition of the exchange-correlation (XC) + *method*. Here, the term *method* is a more general concept than just *functionals* + and include, e.g., post Hartree-Fock methods, too. + ''' + + m_def = Category( + aliases=['settings_XC'], + categories=[SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_XC')) + + +class TimeInfo(MCategory): + ''' + Stores information on the date and timings of the calculation. They are useful for, + e.g., debugging or visualization purposes. + ''' + + m_def = Category( + aliases=['time_info'], + categories=[AccessoryInfo], + a_legacy=LegacyDefinition(name='time_info')) + + +class EnergyTotalPotentialPerAtom(MCategory): + ''' + A value of the total potential energy per atom. Note that a direct comparison may not + be possible because of a difference in the methods for computing total energies and + numerical implementations of various codes might leads to different energy zeros (see + section_energy_code_independent for a code-independent definition of the energy). + ''' + + m_def = Category( + aliases=['energy_total_potential_per_atom'], + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_total_potential_per_atom')) + + +class EnergyTotalPotential(MCategory): + ''' + A value of the total potential energy. Note that a direct comparison may not be + possible because of a difference in the methods for computing total energies and + numerical implementations of various codes might leads to different energy zeros (see + section_energy_code_independent for a code-independent definition of the energy). + ''' + + m_def = Category( + aliases=['energy_total_potential'], + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_total_potential')) + + +class EnergyTypeC(MCategory): + ''' + This metadata stores the correlation (C) energy. + ''' + + m_def = Category( + aliases=['energy_type_C'], + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_type_C')) + + +class EnergyTypeVanDerWaals(MCategory): + ''' + This metadata stores the converged van der Waals energy. + ''' + + m_def = Category( + aliases=['energy_type_van_der_Waals'], + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_type_van_der_Waals')) + + +class EnergyTypeXC(MCategory): + ''' + This metadata stores the exchange-correlation (XC) energy. + ''' + + m_def = Category( + aliases=['energy_type_XC'], + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_type_XC')) + + +class EnergyTypeX(MCategory): + ''' + This metadata stores the exchange (X) energy. + ''' + + m_def = Category( + aliases=['energy_type_X'], + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_type_X')) + + +class MessageWarning(MCategory): + ''' + A warning message of the computational program. + ''' + + m_def = Category( + aliases=['message_warning'], + categories=[MessageInfo, MessageDebug], + a_legacy=LegacyDefinition(name='message_warning')) + + +class ParsingMessageWarning(MCategory): + ''' + This field is used for warning messages of the parsing program. + ''' + + m_def = Category( + aliases=['parsing_message_warning'], + categories=[ParsingMessageInfo, ParsingMessageDebug], + a_legacy=LegacyDefinition(name='parsing_message_warning')) + + +class SettingsBarostat(MCategory): + ''' + Contains parameters controlling the barostat in a molecular dynamics calculation. + ''' + + m_def = Category( + aliases=['settings_barostat'], + categories=[SettingsSampling, SettingsMolecularDynamics], + a_legacy=LegacyDefinition(name='settings_barostat')) + + +class SettingsIntegrator(MCategory): + ''' + Contains parameters that control the molecular dynamics (MD) integrator. + ''' + + m_def = Category( + aliases=['settings_integrator'], + categories=[SettingsSampling, SettingsMolecularDynamics], + a_legacy=LegacyDefinition(name='settings_integrator')) + + +class SettingsPostHartreeFock(MCategory): + ''' + Contains parameters for the post Hartree-Fock method. + ''' + + m_def = Category( + aliases=['settings_post_hartree_fock'], + categories=[SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_post_hartree_fock')) + + +class SettingsRelativity(MCategory): + ''' + Contains parameters and information connected with the relativistic treatment used in + the calculation. + ''' + + m_def = Category( + aliases=['settings_relativity'], + categories=[SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_relativity')) + + +class SettingsSelfInteractionCorrection(MCategory): + ''' + Contains parameters and information connected with the self-interaction correction + (SIC) method being used in self_interaction_correction_method. + ''' + + m_def = Category( + aliases=['settings_self_interaction_correction'], + categories=[SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_self_interaction_correction')) + + +class SettingsThermostat(MCategory): + ''' + Contains parameters that control the thermostat in the molecular dynamics (MD) + calculations. + ''' + + m_def = Category( + aliases=['settings_thermostat'], + categories=[SettingsSampling, SettingsMolecularDynamics], + a_legacy=LegacyDefinition(name='settings_thermostat')) + + +class SettingsVanDerWaals(MCategory): + ''' + Contain parameters and information connected with the Van der Waals treatment used in + the calculation to compute the Van der Waals energy (energy_van_der_Waals). + ''' + + m_def = Category( + aliases=['settings_van_der_Waals'], + categories=[SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_van_der_Waals')) + + +class SettingsXCFunctional(MCategory): + ''' + Contain parameters connected with the definition of the exchange-correlation (XC) + functional (see section_XC_functionals and XC_functional). + ''' + + m_def = Category( + aliases=['settings_XC_functional'], + categories=[SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_XC_functional')) + + +class MessageError(MCategory): + ''' + An error message of the computational program. + ''' + + m_def = Category( + aliases=['message_error'], + categories=[MessageInfo, MessageDebug, MessageWarning], + a_legacy=LegacyDefinition(name='message_error')) + + +class ParsingMessageError(MCategory): + ''' + This field is used for error messages of the parsing program. + ''' + + m_def = Category( + aliases=['parsing_message_error'], + categories=[ParsingMessageInfo, ParsingMessageWarning, ParsingMessageDebug], + a_legacy=LegacyDefinition(name='parsing_message_error')) + + +class SettingsCoupledCluster(MCategory): + ''' + Contains parameters for the coupled-cluster method (CC) in the post Hartree-Fock step. + ''' + + m_def = Category( + aliases=['settings_coupled_cluster'], + categories=[SettingsPostHartreeFock, SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_coupled_cluster')) + + +class SettingsGW(MCategory): + ''' + Contains parameters for the GW-method in the post Hartree-Fock step, that expands the + self-energy in terms of the single particle Green's function $G$ and the screened + Coulomb interaction $W$. + ''' + + m_def = Category( + aliases=['settings_GW'], + categories=[SettingsPostHartreeFock, SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_GW')) + + +class SettingsMCSCF(MCategory): + ''' + Contains parameters for the multi-configurational self-consistent-field (MCSCF) + method. + ''' + + m_def = Category( + aliases=['settings_MCSCF'], + categories=[SettingsPostHartreeFock, SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_MCSCF')) + + +class SettingsMollerPlessetPerturbationTheory(MCategory): + ''' + Contains parameters for Møller–Plesset perturbation theory. + ''' + + m_def = Category( + aliases=['settings_moller_plesset_perturbation_theory'], + categories=[SettingsPostHartreeFock, SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_moller_plesset_perturbation_theory')) + + +class SettingsMultiReference(MCategory): + ''' + Contains parameters for the multi-reference single and double configuration + interaction method. + ''' + + m_def = Category( + aliases=['settings_multi_reference'], + categories=[SettingsPostHartreeFock, SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='settings_multi_reference')) + + +class ArchiveContext(MSection): + ''' + Contains information relating to an archive. + ''' + + m_def = Section( + aliases=['archive_context'], + validate=False, + a_legacy=LegacyDefinition(name='archive_context')) + + archive_gid = Quantity( + type=str, + shape=[], + description=''' + unique identifier of an archive. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='archive_gid')) + + +class CalculationContext(MSection): + ''' + Contains information relating to a calculation. + ''' + + m_def = Section( + aliases=['calculation_context'], + validate=False, + a_legacy=LegacyDefinition(name='calculation_context')) + + calculation_gid = Quantity( + type=str, + shape=[], + description=''' + unique identifier of a calculation. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='calculation_gid')) + + +class AtomProjectedDos(MSection): + ''' + Section collecting the information on an atom projected density of states (DOS) + evaluation. + ''' + + m_def = Section( + aliases=['section_atom_projected_dos'], + validate=False, + a_legacy=LegacyDefinition(name='section_atom_projected_dos')) + + atom_projected_dos_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atom_projected_dos_values'], + unit='joule', + description=''' + Array containing the set of discrete energy values for the atom-projected density + (electronic-energy) of states (DOS). + ''', + a_legacy=LegacyDefinition(name='atom_projected_dos_energies')) + + atom_projected_dos_lm = Quantity( + type=np.dtype(np.int32), + shape=['number_of_lm_atom_projected_dos', 2], + description=''' + Tuples of $l$ and $m$ values for which atom_projected_dos_values_lm are given. For + the quantum number $l$ the conventional meaning of azimuthal quantum number is + always adopted. For the integer number $m$, besides the conventional use as + magnetic quantum number ($l+1$ integer values from $-l$ to $l$), a set of + different conventions is accepted (see the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). + The adopted convention is specified by atom_projected_dos_m_kind. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='atom_projected_dos_lm')) + + atom_projected_dos_m_kind = Quantity( + type=str, + shape=[], + description=''' + String describing what the integer numbers of $m$ in atom_projected_dos_lm mean. + The allowed values are listed in the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). + ''', + a_legacy=LegacyDefinition(name='atom_projected_dos_m_kind')) + + atom_projected_dos_values_lm = Quantity( + type=np.dtype(np.float64), + shape=['number_of_lm_atom_projected_dos', 'number_of_spin_channels', 'number_of_atoms', 'number_of_atom_projected_dos_values'], + description=''' + Values correspond to the number of states for a given energy (the set of discrete + energy values is given in atom_projected_dos_energies) divided into contributions + from each $l,m$ channel for the atom-projected density (electronic-energy) of + states. Here, there are as many atom-projected DOS as the number_of_atoms, the + list of labels of the atoms and their meanings are in atom_labels. + ''', + a_legacy=LegacyDefinition(name='atom_projected_dos_values_lm')) + + atom_projected_dos_values_total = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_atoms', 'number_of_atom_projected_dos_values'], + description=''' + Values correspond to the number of states for a given energy (the set of discrete + energy values is given in atom_projected_dos_energies) divided into contributions + summed up over all $l$ channels for the atom-projected density (electronic-energy) + of states (DOS). Here, there are as many atom-projected DOS as the + number_of_atoms, the list of labels of the atoms and their meanings are in + atom_labels. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='atom_projected_dos_values_total')) + + number_of_atom_projected_dos_values = Quantity( + type=int, + shape=[], + description=''' + Gives the number of energy values for the atom-projected density of states (DOS) + based on atom_projected_dos_values_lm and atom_projected_dos_values_total. + ''', + a_legacy=LegacyDefinition(name='number_of_atom_projected_dos_values')) + + number_of_lm_atom_projected_dos = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $l$, $m$ combinations for the atom projected density of states + (DOS) defined in section_atom_projected_dos. + ''', + a_legacy=LegacyDefinition(name='number_of_lm_atom_projected_dos')) + + +class AtomicMultipoles(MSection): + ''' + Section describing multipoles (charges/monopoles, dipoles, quadrupoles, ...) for each + atom. + ''' + + m_def = Section( + aliases=['section_atomic_multipoles'], + validate=False, + a_legacy=LegacyDefinition(name='section_atomic_multipoles')) + + atomic_multipole_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the method used to obtain the electrostatic multipoles + (including the electric charge, dipole, etc.) for each atom. Such multipoles + require a charge-density partitioning scheme, specified by the value of this + metadata. Allowed values are listed in the [atomic_multipole_kind wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/atomic- + multipole-kind). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='atomic_multipole_kind')) + + atomic_multipole_lm = Quantity( + type=np.dtype(np.int32), + shape=['number_of_lm_atomic_multipoles', 2], + description=''' + Tuples of $l$ and $m$ values for which the atomic multipoles (including the + electric charge, dipole, etc.) are given. The method used to obtain the multipoles + is specified by atomic_multipole_kind. The meaning of the integer number $l$ is + monopole/charge for $l=0$, dipole for $l=1$, quadrupole for $l=2$, etc. The + meaning of the integer numbers $m$ is specified by atomic_multipole_m_kind. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='atomic_multipole_lm')) + + atomic_multipole_m_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the definition for each integer number $m$ in + atomic_multipole_lm. Allowed values are listed in the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='atomic_multipole_m_kind')) + + atomic_multipole_values = Quantity( + type=np.dtype(np.float64), + shape=['number_of_lm_atomic_multipoles', 'number_of_atoms'], + description=''' + Value of the multipoles (including the monopole/charge for $l$ = 0, the dipole for + $l$ = 1, etc.) for each atom, calculated as described in atomic_multipole_kind. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='atomic_multipole_values')) + + number_of_lm_atomic_multipoles = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $l$, $m$ combinations for atomic multipoles + atomic_multipole_lm. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_lm_atomic_multipoles')) + + +class BasisFunctionsAtomCentered(MSection): + ''' + This section contains the description of the basis functions (at least one function) + of the (atom-centered) basis set defined in section_basis_set_atom_centered. + ''' + + m_def = Section( + aliases=['section_basis_functions_atom_centered'], + validate=False, + a_legacy=LegacyDefinition(name='section_basis_functions_atom_centered')) + + +class BasisSetAtomCentered(MSection): + ''' + This section describes the atom-centered basis set. The main contained information is + a short, non unique but human-interpretable, name for identifying the basis set + (basis_set_atom_centered_short_name), a longer, unique name + (basis_set_atom_centered_unique_name), the atomic number of the atomic species the + basis set is meant for (basis_set_atom_number), and a list of actual basis functions + in the section_basis_functions_atom_centered section. + ''' + + m_def = Section( + aliases=['section_basis_set_atom_centered'], + validate=False, + a_legacy=LegacyDefinition(name='section_basis_set_atom_centered')) + + basis_set_atom_centered_ls = Quantity( + type=np.dtype(np.int32), + shape=['number_of_kinds_in_basis_set_atom_centered'], + description=''' + Azimuthal quantum number ($l$) values (of the angular part given by the spherical + harmonic $Y_{lm}$) of the atom-centered basis function defined in the current + section_basis_set_atom_centered. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='basis_set_atom_centered_ls')) + + basis_set_atom_centered_radial_functions = Quantity( + type=np.dtype(np.float64), + shape=['number_of_kinds_in_basis_set_atom_centered', 401, 5], + description=''' + Values of the radial function of the different basis function kinds. The values + are numerically tabulated on a default 0.01-nm equally spaced grid from 0 to 4 nm. + The 5 tabulated values are $r$, $f(r)$, $f'(r)$, $f(r) \\cdot r$, + $\\frac{d}{dr}(f(r) \\cdot r)$. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='basis_set_atom_centered_radial_functions')) + + basis_set_atom_centered_short_name = Quantity( + type=str, + shape=[], + description=''' + Code-specific, but explicative, base name for the basis set (not unique). Details + are explained in the [basis_set_atom_centered_short_name wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- + set-atom-centered-short-name), this name should not contain the *atom kind* (to + simplify the use of a single name for multiple elements). + ''', + a_legacy=LegacyDefinition(name='basis_set_atom_centered_short_name')) + + basis_set_atom_centered_unique_name = Quantity( + type=str, + shape=[], + description=''' + Code-specific, but explicative, base name for the basis set (not unique). This + string starts with basis_set_atom_centered_short_name. If the basis set defined in + this section_basis_set_atom_centered is not identical to the default definition + (stored in a database) of the basis set with the same name stored in a database, + then the string is extended by 10 identifiable characters as explained in the + [basis_set_atom_centered_name wiki page](https://gitlab.mpcdf.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/basis-set-atom-centered-unique-name). The + reason for this procedure is that often atom-centered basis sets are obtained by + fine tuning basis sets provided by the code developers or other sources. Each + basis sets, which has normally a standard name, often reported in publications, + has also several parameters that can be tuned. This metadata tries to keep track + of the original basis set and its modifications. This string here defined should + not contain the *atom kind* for which this basis set is intended for, in order to + simplify the use of a single name for multiple *atom kinds* (see atom_labels for + the actual meaning of *atom kind*). + ''', + a_legacy=LegacyDefinition(name='basis_set_atom_centered_unique_name')) + + basis_set_atom_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Atomic number (i.e., number of protons) of the atom for which this basis set is + constructed (0 means unspecified or a pseudo atom). + ''', + a_legacy=LegacyDefinition(name='basis_set_atom_number')) + + number_of_basis_functions_in_basis_set_atom_centered = Quantity( + type=int, + shape=[], + description=''' + Gives the number of different basis functions in a section_basis_set_atom_centered + section. This equals the number of actual coefficients that are specified when + using this basis set. + ''', + a_legacy=LegacyDefinition(name='number_of_basis_functions_in_basis_set_atom_centered')) + + number_of_kinds_in_basis_set_atom_centered = Quantity( + type=int, + shape=[], + description=''' + Gives the number of different *kinds* of radial basis functions in the + section_basis_set_atom_centered section. Specifically, basis functions with the + same $n$ and $l$ quantum numbers are grouped in sets. Each set counts as one + *kind*. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_kinds_in_basis_set_atom_centered')) + + section_basis_functions_atom_centered = SubSection( + sub_section=SectionProxy('BasisFunctionsAtomCentered'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_basis_functions_atom_centered')) + + section_gaussian_basis_group = SubSection( + sub_section=SectionProxy('GaussianBasisGroup'), + repeats=True, + a_legacy=LegacyDefinition(name='section_gaussian_basis_group')) + + +class BasisSetCellDependent(MSection): + ''' + Section describing a cell-dependent (atom-independent) basis set, e.g. plane waves. + The contained information is the type of basis set (in basis_set_cell_dependent_kind), + its parameters (e.g., for plane waves in basis_set_planewave_cutoff), and a name that + identifies the actually used basis set (a string combining the type and the + parameter(s), stored in basis_set_cell_dependent_name). + ''' + + m_def = Section( + aliases=['section_basis_set_cell_dependent'], + validate=False, + a_legacy=LegacyDefinition(name='section_basis_set_cell_dependent')) + + basis_set_cell_dependent_kind = Quantity( + type=str, + shape=[], + description=''' + A string defining the type of the cell-dependent basis set (i.e., non atom + centered such as plane-waves). Allowed values are listed in the + [basis_set_cell_dependent_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/basis-set-cell-dependent-kind). + ''', + a_legacy=LegacyDefinition(name='basis_set_cell_dependent_kind')) + + basis_set_cell_dependent_name = Quantity( + type=str, + shape=[], + description=''' + A label identifying the cell-dependent basis set (i.e., non atom centered such as + plane-waves). Allowed values are listed in the [basis_set_cell_dependent_name wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- + set-cell-dependent-name). + ''', + a_legacy=LegacyDefinition(name='basis_set_cell_dependent_name')) + + basis_set_planewave_cutoff = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Spherical cutoff in reciprocal space for a plane-wave basis set. It is the energy + of the highest plan-ewave ($\\frac{\\hbar^2|k+G|^2}{2m_e}$) included in the basis + set. Note that normally this basis set is used for the wavefunctions, and the + density would have 4 times the cutoff, but this actually depends on the use of the + basis set by the method. + ''', + a_legacy=LegacyDefinition(name='basis_set_planewave_cutoff')) + + +class BasisSet(MSection): + ''' + This section contains references to *all* basis sets used in this + section_single_configuration_calculation. More than one basis set instance per *single + configuration calculation* (see section_single_configuration_calculation) may be + needed. This is true for example, for codes that implement adaptive basis sets along + the self-consistent field (SCF) convergence (e.g., exciting). In such cases, there is + a section_basis_set instance per SCF iteration, if necessary. Another example is + having a basis set for wavefunctions, a different one for the density, an auxiliary + basis set for resolution of identity (RI), etc. + + Supported are the two broad classes of basis sets: *atom-centered* (e.g., Gaussian- + type, numerical atomic orbitals) and *cell-dependent* (like plane waves or real-space + grids, so named because they are typically used for periodic-system calculations and + dependent to the simulated cell as a whole). + + Basis sets used in this section_single_configuration_calculation, belonging to either + class, are defined in the dedicated section: [section_basis_set_cell_dependent + ](section_basis_set_cell_dependent) or section_basis_set_atom_centered. The + correspondence between the basis sets listed in this section and the definition given + in the dedicated sessions is given by the two concrete metadata: + mapping_section_basis_set_cell_dependent and mapping_section_basis_set_atom_centered. + The latter metadata is a list that connects each atom in the system with its basis + set, where the same basis set can be assigned to more than one atom. + ''' + + m_def = Section( + aliases=['section_basis_set'], + validate=False, + a_legacy=LegacyDefinition(name='section_basis_set')) + + basis_set_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the use of the basis set, i.e, if it used for expanding a wave- + function or an electron density. Allowed values are listed in the [basis_set_kind + wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/basis-set-kind). + ''', + a_legacy=LegacyDefinition(name='basis_set_kind')) + + basis_set_name = Quantity( + type=str, + shape=[], + description=''' + String identifying the basis set in an unique way. The rules for building this + string are specified in the [basis_set_name wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- + set-name). + ''', + a_legacy=LegacyDefinition(name='basis_set_name')) + + mapping_section_basis_set_atom_centered = Quantity( + type=Reference(SectionProxy('BasisSetAtomCentered')), + shape=['number_of_atoms'], + description=''' + An array of the dimension of number_of_atoms where each atom (identified by the + index in the array) is assigned to an atom-centered basis set, for this + section_single_configuration_calculation. The actual definition of the atom- + centered basis set is in the section_basis_set_atom_centered that is referred to + by this metadata. + ''', + a_legacy=LegacyDefinition(name='mapping_section_basis_set_atom_centered')) + + mapping_section_basis_set_cell_dependent = Quantity( + type=Reference(SectionProxy('BasisSetCellDependent')), + shape=[], + description=''' + Assignment of the cell-dependent (i.e., non atom centered, e.g., plane-waves) + parts of the basis set, which is defined (type, parameters) in + section_basis_set_cell_dependent that is referred to by this metadata. + ''', + a_legacy=LegacyDefinition(name='mapping_section_basis_set_cell_dependent')) + + number_of_basis_functions = Quantity( + type=int, + shape=[], + description=''' + Stores the total number of basis functions in a section_basis_set section. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_basis_functions')) + + +class RestrictedUri(MSection): + ''' + Restricted URIs on this calculation (Coverage: any info or files that are related with + this calculation can be subject to restriction) + ''' + + m_def = Section( + aliases=['section_restricted_uri'], + validate=False, + a_legacy=LegacyDefinition(name='section_restricted_uri')) + + number_of_restricted_uri = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + The number of restricted uris in restricted_uri list. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_restricted_uri')) + + restricted_uri = Quantity( + type=str, + shape=['number_of_restricted_uri'], + description=''' + The list of nomad uri(s) identifying the restricted info/file corresponding to + this calculation + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='restricted_uri')) + + restricted_uri_reason = Quantity( + type=str, + shape=[], + description=''' + The reason of restriction for the uri or file. The reason can be 'propriety + license', 'open-source redistribution restricted license', 'other license', or + 'author restricted'. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='restricted_uri_reason')) + + restricted_uri_issue_authority = Quantity( + type=str, + shape=[], + description=''' + The issue authority is the restriction owner for the uri or file. This can be + license owner such as 'VASP' or 'AMBER', 'NOMAD', or the author of the uri. For + example the repository user name of the author. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='restricted_uri_issue_authority')) + + restricted_uri_end_date = Quantity( + type=str, + shape=[], + description=''' + The deadline date of the restriction for the uri or file. The end date can be in + date format string for those restrictions set by authors or NOMAD otherwise it is + set to 'unlimited' for the restriction related to license. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='restricted_uri_end_date')) + + restricted_uri_restriction = Quantity( + type=str, + shape=[], + description=''' + The type of restriction for the uri or file. The type can be 'any access' or + 'license permitted'. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='restricted_uri_restriction')) + + restricted_uri_license = Quantity( + type=str, + shape=[], + description=''' + The info of the license that is the reason of restriction. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='restricted_uri_license')) + + number_of_restricted_uri_files = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + The number of restricted files in restricted_uri_files list. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_restricted_uri_files')) + + +class CalculationToCalculationRefs(MSection): + ''' + Section that describes the relationship between different + section_single_configuration_calculation sections. + + For instance, one calculation is a perturbation performed using a self-consistent + field (SCF) calculation as starting point, or a simulated system is partitioned in + regions with different but connected Hamiltonians (e.g., QM/MM, or a region treated + via Kohn-Sham DFT embedded into a region treated via orbital-free DFT). + + The kind of relationship between the calculation defined in this section and the + referenced one is described by calculation_to_calculation_kind. The referenced + section_single_configuration_calculation is identified via + calculation_to_calculation_ref (typically used for a + section_single_configuration_calculation in the same section_run) or + calculation_to_calculation_external_url. + ''' + + m_def = Section( + aliases=['section_calculation_to_calculation_refs'], + validate=False, + a_legacy=LegacyDefinition(name='section_calculation_to_calculation_refs')) + + calculation_to_calculation_external_url = Quantity( + type=str, + shape=[], + description=''' + URL used to reference an externally stored calculation. The kind of relationship + between the present and the referenced section_single_configuration_calculation is + specified by calculation_to_calculation_kind. + ''', + a_legacy=LegacyDefinition(name='calculation_to_calculation_external_url')) + + calculation_to_calculation_kind = Quantity( + type=str, + shape=[], + description=''' + String defining the relationship between the referenced + section_single_configuration_calculation and the present + section_single_configuration_calculation. Valid values are described in the + [calculation_to_calculation_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/calculation-to-calculation-kind). Often + calculations are connected, for instance, one calculation is a perturbation + performed using a self-consistent field (SCF) calculation as starting point, or a + simulated system is partitioned in regions with different but connected + Hamiltonians (e.g., QM/MM, or a region treated via Kohn-Sham DFT embedded into a + region treated via orbital-free DFT). Hence, the need of keeping track of these + connected calculations. The referenced calculation is identified via + calculation_to_calculation_ref (typically used for a calculation in the same + section_run) or calculation_to_calculation_external_url. + ''', + a_legacy=LegacyDefinition(name='calculation_to_calculation_kind')) + + calculation_to_calculation_ref = Quantity( + type=Reference(SectionProxy('SingleConfigurationCalculation')), + shape=[], + description=''' + Reference to another calculation. If both this and + calculation_to_calculation_external_url are given, then + calculation_to_calculation_ref is a local copy of the URL given in + calculation_to_calculation_external_url. The kind of relationship between the + present and the referenced section_single_configuration_calculation is specified + by calculation_to_calculation_kind. + ''', + a_legacy=LegacyDefinition(name='calculation_to_calculation_ref')) + + +class CalculationToFolderRefs(MSection): + ''' + Section that describes the relationship between + section_single_configuration_calculationa and the folder containing the original + calulations + ''' + + m_def = Section( + aliases=['section_calculation_to_folder_refs'], + validate=False, + a_legacy=LegacyDefinition(name='section_calculation_to_folder_refs')) + + calculation_to_folder_external_url = Quantity( + type=str, + shape=[], + description=''' + URL used to reference a folder containing external calculations. The kind of + relationship between the present and the referenced + section_single_configuration_calculation is specified by + calculation_to_folder_kind. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='calculation_to_folder_external_url')) + + calculation_to_folder_kind = Quantity( + type=str, + shape=[], + description=''' + String defining the relationship between the referenced + section_single_configuration_calculation and a folder containing calculations. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='calculation_to_folder_kind')) + + +class DosFingerprint(MSection): + ''' + Section for the fingerprint of the electronic density-of-states (DOS). DOS + fingerprints are a modification of the D-Fingerprints reported in Chem. Mater. 2015, + 27, 3, 735–743 (doi:10.1021/cm503507h). The fingerprint consists of a binary + representation of the DOS, that is used to evaluate the similarity of materials based + on their electronic structure. + ''' + + m_def = Section( + aliases=['section_dos_fingerprint'], + validate=False, + a_legacy=LegacyDefinition(name='section_dos_fingerprint')) + + bins = Quantity( + type=str, + shape=[], + description=''' + Byte representation of the DOS fingerprint. + ''', + a_legacy=LegacyDefinition(name='bins')) + + indices = Quantity( + type=np.dtype(np.int16), + shape=[2], + description=''' + Indices used to compare DOS fingerprints of different energy ranges. + ''', + a_legacy=LegacyDefinition(name='indices')) + + stepsize = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Stepsize of interpolation in the first step of the generation of DOS fingerprints. + ''', + a_legacy=LegacyDefinition(name='stepsize')) + + filling_factor = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Proportion of 1 bins in the DOS fingerprint. + ''', + a_legacy=LegacyDefinition(name='filling_factor')) + + grid_id = Quantity( + type=str, + shape=[], + description=''' + Identifier of the DOS grid that was used for the creation of the fingerprint. + Similarity can only be calculated if the same grid was used for both fingerprints. + ''', + a_legacy=LegacyDefinition(name='grid_id')) + + +class Dos(MSection): + ''' + Section collecting information of a (electronic-energy or vibrational-energy) density + of states (DOS) evaluation. + ''' + + m_def = Section( + aliases=['section_dos'], + validate=False, + a_legacy=LegacyDefinition(name='section_dos')) + + dos_energies_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_dos_values'], + unit='joule', + description=''' + Array containing the set of discrete energy values with respect to the highest + occupied energy level. This is the total DOS, see atom_projected_dos_energies and + species_projected_dos_energies for partial density of states. + + If not available through energy_reference_highest_occupied, the highest occupied + energy level is detected by searching for a non-zero DOS value below (or nearby) + the reported energy_reference_fermi. In case the highest occupied energy level + cannot be detected accurately, the normalized values are not reported. For + calculations with multiple spin-channels, the normalization is determined by the + first channel. + ''', + a_legacy=LegacyDefinition(name='dos_energies_normalized')) + + dos_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_dos_values'], + unit='joule', + description=''' + Array containing the set of discrete energy values for the density (electronic- + energy or vibrational energy) of states (DOS). This is the total DOS, see + atom_projected_dos_energies and species_projected_dos_energies for partial density + of states. + ''', + a_legacy=LegacyDefinition(name='dos_energies')) + + dos_integrated_values = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_dos_values'], + description=''' + Integrated density of states (starting at $-\\infty$), pseudo potential + calculations should start with the number of core electrons if they cover only the + active electrons + ''', + a_legacy=LegacyDefinition(name='dos_integrated_values')) + + dos_kind = Quantity( + type=str, + shape=[], + description=''' + String to specify the kind of density of states (either electronic or + vibrational). + ''', + a_legacy=LegacyDefinition(name='dos_kind')) + + dos_lm = Quantity( + type=np.dtype(np.int32), + shape=['number_of_dos_lms', 2], + description=''' + Tuples of $l$ and $m$ values for which dos_values_lm are given. For the quantum + number $l$ the conventional meaning of azimuthal quantum number is always adopted. + For the integer number $m$, besides the conventional use as magnetic quantum + number ($l+1$ integer values from $-l$ to $l$), a set of different conventions is + accepted (see the [m_kind wiki page](https://gitlab.rzg.mpg.de/nomad-lab/nomad- + meta-info/wikis/metainfo/m-kind). The actual adopted convention is specified by + dos_m_kind. + ''', + a_legacy=LegacyDefinition(name='dos_lm')) + + dos_m_kind = Quantity( + type=str, + shape=[], + description=''' + String describing what the integer numbers of $m$ in dos_lm mean. The allowed + values are listed in the [m_kind wiki page](https://gitlab.rzg.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/m-kind). + ''', + a_legacy=LegacyDefinition(name='dos_m_kind')) + + dos_values_lm = Quantity( + type=np.dtype(np.float64), + shape=['number_of_dos_lms', 'number_of_spin_channels', 'number_of_atoms', 'number_of_dos_values'], + unit='joule', + description=''' + Array containing the density (electronic-energy) of states values projected on the + various spherical harmonics (integrated on all atoms), see + atom_projected_dos_values_lm for atom values. + ''', + a_legacy=LegacyDefinition(name='dos_values_lm')) + + dos_values_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_dos_values'], + description=''' + Density of states (DOS) values divided by the unit cell volume and by the number + of atoms. + ''', + a_legacy=LegacyDefinition(name='dos_values_normalized')) + + dos_values = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_dos_values'], + description=''' + Values (number of states for a given energy, the set of discrete energy values is + given in dos_energies) of density (electronic-energy or vibrational-energy) of + states. This refers to the simulation cell, i.e. integrating over all energies + will give the number of electrons in the simulation cell. + ''', + a_legacy=LegacyDefinition(name='dos_values')) + + number_of_dos_lms = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $l$, $m$ combinations for the given projected density of + states (DOS) in dos_values and dos_values_lm. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_dos_lms')) + + number_of_dos_values = Quantity( + type=int, + shape=[], + description=''' + Gives the number of energy values for the density of states (DOS), see + dos_energies. + ''', + a_legacy=LegacyDefinition(name='number_of_dos_values')) + + section_dos_fingerprint = SubSection( + sub_section=SectionProxy('DosFingerprint'), + repeats=False, + a_legacy=LegacyDefinition(name='section_dos_fingerprint')) + + +class Eigenvalues(MSection): + ''' + Section containing (electronic-energy) eigenvalues for one spin channel. If, for + example, the eigenvalues of the Kohn-Sham operator are to be stored, a string + identifying this kind of eigenvalues is put in eigenvalues_kind, the coordinates of + the $k$-points at which the eigenvalues are evaluated is stored in + eigenvalues_kpoints, and the energy values of the eigenstates and their occupation is + stored in eigenvalues_values and eigenvalues_occupation, respectively. + ''' + + m_def = Section( + aliases=['section_eigenvalues'], + validate=False, + a_legacy=LegacyDefinition(name='section_eigenvalues')) + + eigenvalues_kind = Quantity( + type=str, + shape=[], + description=''' + A short string describing the kind of eigenvalues, as defined in the + [eigenvalues_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/eigenvalues-kind). + ''', + a_legacy=LegacyDefinition(name='eigenvalues_kind')) + + eigenvalues_kpoints_multiplicity = Quantity( + type=np.dtype(np.float64), + shape=['number_of_eigenvalues_kpoints'], + description=''' + Multiplicity of the $k$ point (i.e., how many distinct points per cell this + expands to after applying all symmetries). This defaults to 1. If expansion is + preformed then each point will have weight + eigenvalues_kpoints_weights/eigenvalues_kpoints_multiplicity. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='eigenvalues_kpoints_multiplicity')) + + eigenvalues_kpoints_weights = Quantity( + type=np.dtype(np.float64), + shape=['number_of_eigenvalues_kpoints'], + description=''' + Weights of the $k$ points (in the basis of the reciprocal lattice vectors) used + for the evaluation of the eigenvalues tabulated in eigenvalues_values, should + account for symmetry too. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='eigenvalues_kpoints_weights')) + + eigenvalues_kpoints = Quantity( + type=np.dtype(np.float64), + shape=['number_of_eigenvalues_kpoints', 3], + description=''' + Coordinates of the $k$ points (in the basis of the reciprocal lattice vectors) + used for the evaluation of the eigenvalues tabulated in eigenvalues_values. + ''', + a_legacy=LegacyDefinition(name='eigenvalues_kpoints')) + + eigenvalues_occupation = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + description=''' + Occupation of the eigenstates. The corresponding eigenvalues (energy) are given in + eigenvalues_values. The coordinates in the reciprocal space are defined in + eigenvalues_kpoints. + ''', + a_legacy=LegacyDefinition(name='eigenvalues_occupation')) + + eigenvalues_values = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Values of the (electronic-energy) eigenvalues. The coordinates of the + corresponding eigenstates in the reciprocal space are defined in + eigenvalues_kpoints and their occupations are given in eigenvalues_occupation. + ''', + a_legacy=LegacyDefinition(name='eigenvalues_values')) + + number_of_band_segment_eigenvalues = Quantity( + type=int, + shape=[], + description=''' + Gives the number of eigenvalues in a band segment, see band_energies. + ''', + a_legacy=LegacyDefinition(name='number_of_band_segment_eigenvalues')) + + number_of_eigenvalues_kpoints = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $k$ points, see eigenvalues_kpoints. $k$ points are calculated + within a run and are irreducible if a symmetry is used. + ''', + a_legacy=LegacyDefinition(name='number_of_eigenvalues_kpoints')) + + number_of_eigenvalues = Quantity( + type=int, + shape=[], + description=''' + Gives the number of eigenvalues, see eigenvalues_values. + ''', + a_legacy=LegacyDefinition(name='number_of_eigenvalues')) + + number_of_normalized_band_segment_eigenvalues = Quantity( + type=int, + shape=[], + description=''' + Gives the number of normalized eigenvalues in a band segment, see + + band_energies_normalized. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_normalized_band_segment_eigenvalues')) + + gw_qp_linearization_prefactor = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + description=''' + Linearization prefactor + ''', + a_legacy=LegacyDefinition(name='gw_qp_linearization_prefactor')) + + +class EnergyCodeIndependent(MSection): + ''' + Section describing a code-independent total energy obtained by subtracting some + reference energy calculated with the same code. It contains the type in + energy_code_independent_kind and the computed code-independent total energy in + energy_code_independent_value. The computed energy allows for comparisons among + different codes and numerical settings. + ''' + + m_def = Section( + aliases=['section_energy_code_independent'], + validate=False, + a_legacy=LegacyDefinition(name='section_energy_code_independent')) + + energy_code_independent_kind = Quantity( + type=str, + shape=[], + description=''' + Type of the code-independent total energy (obtained by subtracting a reference + energy calculated with the same code), created to be comparable among different + codes and numerical settings. Details can be found on the [energy_code_independent + wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/energy-code-independent). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='energy_code_independent_kind')) + + energy_code_independent_value = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the code-independent total energy (obtained by subtracting a reference + energy calculated with the same code). This value is created to be comparable + among different codes and numerical settings. Details can be found on the + [energy_code_independent wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- + meta-info/wikis/metainfo/energy-code-independent). + ''', + categories=[EnergyComponent, EnergyValue, EnergyTotalPotential, Unused], + a_legacy=LegacyDefinition(name='energy_code_independent_value')) + + +class EnergyVanDerWaals(MSection): + ''' + Section containing the Van der Waals energy value (energy_van_der_Waals_value) of type + van_der_Waals_kind. This is used when more than one Van der Waals methods are applied + in the same *single configuration calculation*, see + section_single_configuration_calculation. The main Van der Waals method (the one + concurring to energy_current, and used, e.g., for evaluating the forces for a + relaxation or dynamics) is given in energy_van_der_Waals and is defined in + settings_van_der_Waals. + ''' + + m_def = Section( + aliases=['section_energy_van_der_Waals'], + validate=False, + a_legacy=LegacyDefinition(name='section_energy_van_der_Waals')) + + energy_van_der_Waals_kind = Quantity( + type=str, + shape=[], + description=''' + Method used to compute van der Waals energy stored in energy_van_der_Waals_value. + This metadata is used when more than one van der Waals method is applied in the + same *single configuration calculation* (see + section_single_configuration_calculation). The method used for van der Waals (the + one consistent with energy_current and, e.g., for evaluating the forces for a + relaxation or dynamics) is defined in settings_van_der_Waals. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='energy_van_der_Waals_kind')) + + energy_van_der_Waals_value = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of van der Waals energy, calculated with the method defined in + energy_van_der_Waals_kind. This metadata is used when more than one van der Waals + method is applied in the same *single configuration calculation* (see + section_single_configuration_calculation). The value of the van der Waals energy + consistent with energy_current and used, e.g., for evaluating the forces for a + relaxation or dynamics, is given in energy_van_der_Waals and defined in + settings_van_der_Waals. + ''', + categories=[EnergyTypeVanDerWaals, EnergyComponent, EnergyValue, Unused], + a_legacy=LegacyDefinition(name='energy_van_der_Waals_value')) + + energy_van_der_Waals = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value for the converged van der Waals energy calculated using the method described + in van_der_Waals_method, and used in energy_current. This is the van der Waals + method consistent with, e.g., forces used for relaxation or dynamics. Alternative + methods are listed in section_energy_van_der_Waals. + ''', + categories=[EnergyTypeVanDerWaals, EnergyComponent, EnergyValue, Unused], + a_legacy=LegacyDefinition(name='energy_van_der_Waals')) + + +class EnergyContribution(MSection): + ''' + Section describing the contributions to the total energy. + ''' + + m_def = Section( + aliases=['section_energy_contribution'], + validate=False, + a_legacy=LegacyDefinition(name='section_energy_contribution')) + + energy_contibution_kind = Quantity( + type=str, + shape=[], + description=''' + The kind of the energy contribution. Can be one of bond, pair, coulomb, etc. + ''', + a_legacy=LegacyDefinition(name='energy_contibution_kind')) + + energy_contribution_value = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the energy contribution. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_contribution_value')) + + +class FrameSequenceUserQuantity(MSection): + ''' + Section collecting some user-defined quantities evaluated along a sequence of frame. + ''' + + m_def = Section( + aliases=['section_frame_sequence_user_quantity'], + validate=False, + a_legacy=LegacyDefinition(name='section_frame_sequence_user_quantity')) + + frame_sequence_user_quantity_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_user_quantity_evaluations_in_sequence'], + description=''' + Array containing the strictly increasing indices referring to the frames of + frame_sequence_user_quantity. If not given it defaults to the trivial mapping + 0,1,... + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='frame_sequence_user_quantity_frames')) + + frame_sequence_user_quantity_name = Quantity( + type=str, + shape=[], + description=''' + Descriptive name of a user-defined quantity, sampled along this sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation). + Dedicated metadata are created for the conserved energy-like quantity + (frame_sequence_conserved_quantity), the kinetic and potential energies + (frame_sequence_kinetic_energy and frame_sequence_potential_energy), the + instantaneous temperature (frame_sequence_temperature) and pressure + (frame_sequence_pressure). This metadata should be used for other quantities that + are monitored along a sequence of frames. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='frame_sequence_user_quantity_name')) + + frame_sequence_user_quantity_stats = Quantity( + type=np.dtype(np.float64), + shape=[2, 'number_of_frame_sequence_user_quantity_components'], + description=''' + Average of frame_sequence_user_quantity and its standard deviation in this + sequence of frames (i.e., a trajectory, a frame is one + section_single_configuration_calculation). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='frame_sequence_user_quantity_stats')) + + frame_sequence_user_quantity = Quantity( + type=np.dtype(np.float64), + shape=['number_of_user_quantity_evaluations_in_sequence', 'number_of_frame_sequence_user_quantity_components'], + description=''' + Array containing the values of the user-defined quantity defined in + frame_sequence_user_quantity_name, evaluated along this sequence of frames (i.e., + trajectory, a frame is one section_single_configuration_calculation). If not all + frames have a value the indices of the frames that have a value are stored in + frame_sequence_kinetic_energy_frames. If not all frames have a value the indices + of the frames that have a value are stored in + frame_sequence_kinetic_energy_frames. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='frame_sequence_user_quantity')) + + number_of_frame_sequence_user_quantity_components = Quantity( + type=int, + shape=[], + description=''' + Gives the number of user-defined quantity defined by + frame_sequence_user_quantity_name and monitored in a sequence of frames. A + sequence is a trajectory, which can have number_of_frames_in_sequence each + representing one section_single_configuration_calculation section. + + Dedicated metadata monitored along a sequence of frames are created for the + conserved energy-like quantity (frame_sequence_conserved_quantity), the kinetic + and potential energies ([frame_sequence_kinetic_energy and + frame_sequence_potential_energy](frame_sequence_kinetic_energy and + frame_sequence_potential_energy)), the instantaneous temperature + (frame_sequence_temperature) and the pressure (frame_sequence_pressure). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_frame_sequence_user_quantity_components')) + + number_of_user_quantity_evaluations_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of user defined quantity evaluations along a sequence of + frame_sequence_user_quantity frames. A sequence is a trajectory, which can have + number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_user_quantity_evaluations_in_sequence')) + + +class FrameSequence(MSection): + ''' + Section containing a sequence of frames, i.e. a trajectory which can have + number_of_frames_in_sequence each representing one + section_single_configuration_calculation section evaluated with a sampling method + (e.g, molecular dynamics, Monte Carlo, geometry optimization). The sampling method + might be a subset of the whole trajectory. + + Information on the method used for the sampling can be found in the + section_sampling_method section and information of each frame of the sequence are + found in the section_single_configuration_calculation section. + ''' + + m_def = Section( + aliases=['section_frame_sequence'], + validate=False, + a_legacy=LegacyDefinition(name='section_frame_sequence')) + + frame_sequence_conserved_quantity_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_conserved_quantity_evaluations_in_sequence'], + description=''' + Array containing the strictly increasing indices of the frames the + frame_sequence_conserved_quantity values refers to. If not given it defaults to + the trivial mapping 0,1,... + ''', + a_legacy=LegacyDefinition(name='frame_sequence_conserved_quantity_frames')) + + frame_sequence_conserved_quantity_stats = Quantity( + type=np.dtype(np.float64), + shape=[2], + unit='joule', + description=''' + Average value of energy-like frame_sequence_conserved_quantity, and its standard + deviation, over this sequence of frames (i.e., a trajectory, a frame is one + section_single_configuration_calculation). + ''', + a_legacy=LegacyDefinition(name='frame_sequence_conserved_quantity_stats')) + + frame_sequence_conserved_quantity = Quantity( + type=np.dtype(np.float64), + shape=['number_of_conserved_quantity_evaluations_in_sequence'], + unit='joule', + description=''' + Array containing the values of a quantity that should be conserved, along a + sequence of frames (i.e., a trajectory). A frame is one + section_single_configuration_calculation), for example the total energy in the NVE + ensemble. If not all frames have a value the indices of the frames that have a + value are stored in frame_sequence_conserved_quantity_frames. + ''', + a_legacy=LegacyDefinition(name='frame_sequence_conserved_quantity')) + + frame_sequence_continuation_kind = Quantity( + type=Reference(SectionProxy('FrameSequence')), + shape=[], + description=''' + Type of continuation that has been performed from the previous sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation), + upon restart. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='frame_sequence_continuation_kind')) + + frame_sequence_external_url = Quantity( + type=str, + shape=[], + description=''' + If the energy, forces, and other quantities for the frames (a frame is one + section_single_configuration_calculation) in section_frame_sequence are obtained + by calling a different code than the code that drives the sequence (e.g., a + wrapper that drives a molecular dynamics, Monte Carlo, geometry optimization and + calls an electronic-structure code for energy and forces for each configuration), + this metadata holds the reference to where the + section_single_configuration_calculation for each frame are located. The format + for this reference is described in the [frame_sequence_external_url wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/frame- + sequence-external-url). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='frame_sequence_external_url')) + + frame_sequence_kinetic_energy_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_kinetic_energies_in_sequence'], + description=''' + Array containing the strictly increasing indices referring to the frames of + frame_sequence_kinetic_energy. If not given it defaults to the trivial mapping + 0,1,... + ''', + a_legacy=LegacyDefinition(name='frame_sequence_kinetic_energy_frames')) + + frame_sequence_kinetic_energy_stats = Quantity( + type=np.dtype(np.float64), + shape=[2], + unit='joule', + description=''' + Average kinetic energy and its standard deviation over this sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation). + ''', + a_legacy=LegacyDefinition(name='frame_sequence_kinetic_energy_stats')) + + frame_sequence_kinetic_energy = Quantity( + type=np.dtype(np.float64), + shape=['number_of_kinetic_energies_in_sequence'], + unit='joule', + description=''' + Array containing the values of the kinetic energy along this sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation). If + not all frames have a value the indices of the frames that have a value are stored + in frame_sequence_kinetic_energy_frames. + ''', + a_legacy=LegacyDefinition(name='frame_sequence_kinetic_energy')) + + frame_sequence_local_frames_ref = Quantity( + type=Reference(SectionProxy('SingleConfigurationCalculation')), + shape=['number_of_frames_in_sequence'], + description=''' + Reference from each frame (a frame is one + section_single_configuration_calculation) in this section_frame_sequence to the + corresponding section_single_configuration_calculation. Each + section_frame_sequence binds a collection of + section_single_configuration_calculation, because they all belong to, e.g., a + molecular dynamics trajectory, or geometry optimization. The full information for + each frame is stored in section_single_configuration_calculation and this metadata + establishes the link for each frame. + ''', + a_legacy=LegacyDefinition(name='frame_sequence_local_frames_ref')) + + frame_sequence_potential_energy_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_potential_energies_in_sequence'], + description=''' + Array containing the strictly increasing indices referring to the frames of + frame_sequence_potential_energy. If not given it defaults to the trivial mapping + 0,1,... + ''', + a_legacy=LegacyDefinition(name='frame_sequence_potential_energy_frames')) + + frame_sequence_potential_energy_stats = Quantity( + type=np.dtype(np.float64), + shape=[2], + unit='joule', + description=''' + Average potential energy and its standard deviation over this sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation). + ''', + a_legacy=LegacyDefinition(name='frame_sequence_potential_energy_stats')) + + frame_sequence_potential_energy = Quantity( + type=np.dtype(np.float64), + shape=['number_of_potential_energies_in_sequence'], + unit='joule', + description=''' + Array containing the value of the potential energy along this sequence of frames + (i.e., a trajectory, a frame is one section_single_configuration_calculation). + This is equal to energy_total of the corresponding + section_single_configuration_calculation and repeated here in a summary array for + easier access. If not all frames have a value the indices of the frames that have + a value are stored in frame_sequence_potential_energy_frames. + ''', + a_legacy=LegacyDefinition(name='frame_sequence_potential_energy')) + + frame_sequence_pressure_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_pressure_evaluations_in_sequence'], + description=''' + Array containing the strictly increasing indices referring to the frames of + frame_sequence_pressure. If not given it defaults to the trivial mapping 0,1,... + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='frame_sequence_pressure_frames')) + + frame_sequence_pressure_stats = Quantity( + type=np.dtype(np.float64), + shape=[2], + unit='pascal', + description=''' + Average pressure (one third of the trace of the stress tensor) and standard + deviation over this sequence of frames (i.e., a trajectory, a frame is one + section_single_configuration_calculation). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='frame_sequence_pressure_stats')) + + frame_sequence_pressure = Quantity( + type=np.dtype(np.float64), + shape=['number_of_pressure_evaluations_in_sequence'], + unit='pascal', + description=''' + Array containing the values of the pressure (one third of the trace of the stress + tensor) along this sequence of frames (a frame is one + section_single_configuration_calculation). If not all frames have a value the + indices of the frames that have a value are stored in + frame_sequence_pressure_frames. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='frame_sequence_pressure')) + + frame_sequence_temperature_frames = Quantity( + type=np.dtype(np.int32), + shape=['number_of_temperatures_in_sequence'], + description=''' + Array containing the strictly increasing indices referring to the frames of + frame_sequence_temperature. If not given it defaults to the trivial mapping + 0,1,... + ''', + a_legacy=LegacyDefinition(name='frame_sequence_temperature_frames')) + + frame_sequence_temperature_stats = Quantity( + type=np.dtype(np.float64), + shape=[2], + unit='kelvin', + description=''' + Average temperature and its standard deviation over this sequence of frames (i.e., + a trajectory, a frame is one section_single_configuration_calculation). + ''', + a_legacy=LegacyDefinition(name='frame_sequence_temperature_stats')) + + frame_sequence_temperature = Quantity( + type=np.dtype(np.float64), + shape=['number_of_temperatures_in_sequence'], + unit='kelvin', + description=''' + Array containing the values of the instantaneous temperature (a quantity, + proportional to frame_sequence_kinetic_energy, whose ensemble average equals the + thermodynamic temperature) along this sequence of frames (i.e., a trajectory, a + frame is one section_single_configuration_calculation). If not all frames have a + value the indices of the frames that have a value are stored in + frame_sequence_temperature_frames. + ''', + a_legacy=LegacyDefinition(name='frame_sequence_temperature')) + + frame_sequence_time = Quantity( + type=np.dtype(np.float64), + shape=['number_of_frames_in_sequence'], + unit='second', + description=''' + Time along this sequence of frames (i.e., a trajectory, a frame is one + section_single_configuration_calculation). Time start is arbitrary, but when a + sequence is a continuation of another time should be continued too. + ''', + a_legacy=LegacyDefinition(name='frame_sequence_time')) + + frame_sequence_to_sampling_ref = Quantity( + type=Reference(SectionProxy('SamplingMethod')), + shape=[], + description=''' + Reference from the present section_frame_sequence to the section_sampling_method, + that defines the parameters used in this sequence of frames (i.e., a trajectory, a + frame is one section_single_configuration_calculation). + ''', + a_legacy=LegacyDefinition(name='frame_sequence_to_sampling_ref')) + + geometry_optimization_converged = Quantity( + type=bool, + shape=[], + description=''' + Arrays specify whether a geometry optimization is converged. + ''', + a_legacy=LegacyDefinition(name='geometry_optimization_converged')) + + number_of_conserved_quantity_evaluations_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of conserved quantity evaluations in this sequence. A sequence is + a trajectory, which can have number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_conserved_quantity_evaluations_in_sequence')) + + number_of_frames_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of frames in a sequence. A sequence is a trajectory, which can + have number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''', + a_legacy=LegacyDefinition(name='number_of_frames_in_sequence')) + + number_of_kinetic_energies_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of kinetic energy evaluations in this sequence of frames, see + frame_sequence_kinetic_energy. + ''', + a_legacy=LegacyDefinition(name='number_of_kinetic_energies_in_sequence')) + + number_of_potential_energies_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of potential energies evaluation in this sequence. A sequence is + a trajectory, which can have number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''', + a_legacy=LegacyDefinition(name='number_of_potential_energies_in_sequence')) + + number_of_pressure_evaluations_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of pressure evaluations in this sequence. A sequence is a + trajectory, which can have number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_pressure_evaluations_in_sequence')) + + number_of_temperatures_in_sequence = Quantity( + type=int, + shape=[], + description=''' + Gives the number of temperature frames (frame_sequence_temperature) used in the + section_frame_sequence. A sequence is a trajectory, which can have + number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_temperatures_in_sequence')) + + previous_sequence_ref = Quantity( + type=Reference(SectionProxy('FrameSequence')), + shape=[], + description=''' + Contains a reference to the previous sequence. A sequence is a trajectory, which + can have number_of_frames_in_sequence each representing one + section_single_configuration_calculation section. If not given, a start from an + initial configuration is assumed. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='previous_sequence_ref')) + + section_frame_sequence_user_quantity = SubSection( + sub_section=SectionProxy('FrameSequenceUserQuantity'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_frame_sequence_user_quantity')) + + section_thermodynamical_properties = SubSection( + sub_section=SectionProxy('ThermodynamicalProperties'), + repeats=True, + a_legacy=LegacyDefinition(name='section_thermodynamical_properties')) + + +class GaussianBasisGroup(MSection): + ''' + Section that describes a group of Gaussian contractions. Groups allow one to calculate + the primitive Gaussian integrals once for several different linear combinations of + them. This defines basis functions with radial part $f_i(r) = r^{l_i} \\sum_{j} c_{i j} + A(l_i, \\alpha_j) exp(-\\alpha_j r^2)$ where $A(l_i, \\alpha_j)$ is a the normalization + coefficient for primitive Gaussian basis functions. Here, $\\alpha_j$ is defined in + gaussian_basis_group_exponents, $l_i$ is given in gaussian_basis_group_ls, and $c_{i + j}$ is given in gaussian_basis_group_contractions, whereas the radial part is given by + the spherical harmonics $Y_{l m}$. + + This section is defined only if the original basis function uses Gaussian basis + functions, and the sequence of radial functions $f_i$ across all + section_gaussian_basis_group in section_basis_set_atom_centered should match the one + of basis_set_atom_centered_radial_functions. + ''' + + m_def = Section( + aliases=['section_gaussian_basis_group'], + validate=False, + a_legacy=LegacyDefinition(name='section_gaussian_basis_group')) + + gaussian_basis_group_contractions = Quantity( + type=np.dtype(np.float64), + shape=['number_of_gaussian_basis_group_contractions', 'number_of_gaussian_basis_group_exponents'], + description=''' + contraction coefficients $c_{i j}$ defining the contracted basis functions with + respect to *normalized* primitive Gaussian functions. They define the Gaussian + basis functions as described in section_gaussian_basis_group. + ''', + a_legacy=LegacyDefinition(name='gaussian_basis_group_contractions')) + + gaussian_basis_group_exponents = Quantity( + type=np.dtype(np.float64), + shape=['number_of_gaussian_basis_group_exponents'], + unit='1 / meter ** 2', + description=''' + Exponents $\\alpha_j$ of the Gaussian functions defining this basis set + $exp(-\\alpha_j r^2)$. One should be careful about the units of the coefficients. + ''', + a_legacy=LegacyDefinition(name='gaussian_basis_group_exponents')) + + gaussian_basis_group_ls = Quantity( + type=np.dtype(np.float64), + shape=['number_of_gaussian_basis_group_contractions'], + description=''' + Azimuthal quantum number ($l$) values (of the angular part given by the spherical + harmonic $Y_{l m}$ of the various contracted basis functions). + ''', + a_legacy=LegacyDefinition(name='gaussian_basis_group_ls')) + + number_of_gaussian_basis_group_contractions = Quantity( + type=int, + shape=[], + description=''' + Gives the number of different contractions, i.e. resulting basis functions in a + section_gaussian_basis_group section. + ''', + a_legacy=LegacyDefinition(name='number_of_gaussian_basis_group_contractions')) + + number_of_gaussian_basis_group_exponents = Quantity( + type=int, + shape=[], + description=''' + Gives the number of different Gaussian exponents in a section_gaussian_basis_group + section. + ''', + a_legacy=LegacyDefinition(name='number_of_gaussian_basis_group_exponents')) + + +class KBandNormalized(MSection): + ''' + This section stores information on a normalized $k$-band (electronic band structure) + evaluation along one-dimensional pathways in the $k$ (reciprocal) space given in + section_k_band_segment. Eigenvalues calculated at the actual $k$-mesh used for + energy_total evaluations, can be found in the section_eigenvalues section. + ''' + + m_def = Section( + aliases=['section_k_band_normalized'], + validate=False, + a_legacy=LegacyDefinition(name='section_k_band_normalized')) + + k_band_path_normalized_is_standard = Quantity( + type=bool, + shape=[], + description=''' + If the normalized path is along the default path defined in W. Setyawan and S. + Curtarolo, [Comput. Mater. Sci. **49**, 299-312 + (2010)](http://dx.doi.org/10.1016/j.commatsci.2010.05.010). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='k_band_path_normalized_is_standard')) + + section_k_band_segment_normalized = SubSection( + sub_section=SectionProxy('KBandSegmentNormalized'), + repeats=True, + a_legacy=LegacyDefinition(name='section_k_band_segment_normalized')) + + +class KBandSegmentNormalized(MSection): + ''' + Section collecting the information on a normalized $k$-band segment. This section + stores band structures along a one-dimensional pathway in the $k$ (reciprocal) space. + + Eigenvalues calculated at the actual $k$-mesh used for energy_total evaluations are + defined in section_eigenvalues and the band structures are represented as third-order + tensors: one dimension for the spin channels, one for the sequence of $k$ points for + the segment (given in number_of_k_points_per_segment), and one for the sequence of + eigenvalues at a given $k$ point. The values of the $k$ points in each segment are + stored in band_k_points. The energies and occupation for each eigenstate, at each $k$ + point, segment, and spin channel are stored in band_energies and band_occupations, + respectively. The labels for the segment are specified in band_segm_labels. + ''' + + m_def = Section( + aliases=['section_k_band_segment_normalized'], + validate=False, + a_legacy=LegacyDefinition(name='section_k_band_segment_normalized')) + + band_energies_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_normalized_k_points_per_segment', 'number_of_normalized_band_segment_eigenvalues'], + unit='joule', + description=''' + $k$-dependent energies of the electronic band segment (electronic band structure) + with respect to the top of the valence band. This is a third-order tensor, with + one dimension used for the spin channels, one for the $k$ points for each segment, + and one for the eigenvalue sequence. + ''', + a_legacy=LegacyDefinition(name='band_energies_normalized')) + + band_k_points_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_normalized_k_points_per_segment', 3], + description=''' + Fractional coordinates of the $k$ points (in the basis of the reciprocal-lattice + vectors) for which the normalized electronic energies are given. + ''', + a_legacy=LegacyDefinition(name='band_k_points_normalized')) + + band_occupations_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_normalized_k_points_per_segment', 'number_of_normalized_band_segment_eigenvalues'], + description=''' + Occupation of the $k$-points along the normalized electronic band. The size of the + dimensions of this third-order tensor are the same as for the tensor in + band_energies. + ''', + a_legacy=LegacyDefinition(name='band_occupations_normalized')) + + band_segm_labels_normalized = Quantity( + type=str, + shape=[2], + description=''' + Start and end labels of the points in the segment (one-dimensional pathways) + sampled in the $k$-space, using the conventional symbols, e.g., Gamma, K, L. The + coordinates (fractional, in the reciprocal space) of the start and end points for + each segment are given in band_segm_start_end_normalized + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='band_segm_labels_normalized')) + + band_segm_start_end_normalized = Quantity( + type=np.dtype(np.float64), + shape=[2, 3], + description=''' + Fractional coordinates of the start and end point (in the basis of the reciprocal + lattice vectors) of the segment sampled in the $k$ space. The conventional symbols + (e.g., Gamma, K, L) of the same points are given in band_segm_labels + ''', + a_legacy=LegacyDefinition(name='band_segm_start_end_normalized')) + + number_of_normalized_k_points_per_segment = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $k$ points in the segment of the normalized band structure + (see section_k_band_segment_normalized). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_normalized_k_points_per_segment')) + + +class KBandSegment(MSection): + ''' + Section collecting the information on a $k$-band or $q$-band segment. This section + stores band structures along a one-dimensional pathway in the $k$ or $q$ (reciprocal) + space. + + Eigenvalues calculated at the actual $k$-mesh used for energy_total evaluations are + defined in section_eigenvalues and the band structures are represented as third-order + tensors: one dimension for the spin channels, one for the sequence of $k$ or $q$ + points for the segment (given in number_of_k_points_per_segment), and one for the + sequence of eigenvalues at a given $k$ or $q$ point. The values of the $k$ or $q$ + points in each segment are stored in band_k_points. The energies and occupation for + each eigenstate, at each $k$ or $q$ point, segment, and spin channel are stored in + band_energies and band_occupations, respectively. The labels for the segment are + specified in band_segm_labels. + ''' + + m_def = Section( + aliases=['section_k_band_segment'], + validate=False, + a_legacy=LegacyDefinition(name='section_k_band_segment')) + + band_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_k_points_per_segment', 'number_of_band_segment_eigenvalues'], + unit='joule', + description=''' + $k$-dependent or $q$-dependent energies of the electronic or vibrational band + segment (electronic/vibrational band structure). This is a third-order tensor, + with one dimension used for the spin channels (1 in case of a vibrational band + structure), one for the $k$ or $q$ points for each segment, and one for the + eigenvalue sequence. + ''', + a_legacy=LegacyDefinition(name='band_energies')) + + band_k_points = Quantity( + type=np.dtype(np.float64), + shape=['number_of_k_points_per_segment', 3], + description=''' + Fractional coordinates of the $k$ or $q$ points (in the basis of the reciprocal- + lattice vectors) for which the electronic energy are given. + ''', + a_legacy=LegacyDefinition(name='band_k_points')) + + band_occupations = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_k_points_per_segment', 'number_of_band_segment_eigenvalues'], + description=''' + Occupation of the $k$-points along the electronic band. The size of the dimensions + of this third-order tensor are the same as for the tensor in band_energies. + ''', + a_legacy=LegacyDefinition(name='band_occupations')) + + band_segm_labels = Quantity( + type=str, + shape=[2], + description=''' + Start and end labels of the points in the segment (one-dimensional pathways) + sampled in the $k$-space or $q$-space, using the conventional symbols, e.g., + Gamma, K, L. The coordinates (fractional, in the reciprocal space) of the start + and end points for each segment are given in band_segm_start_end + ''', + a_legacy=LegacyDefinition(name='band_segm_labels')) + + band_segm_start_end = Quantity( + type=np.dtype(np.float64), + shape=[2, 3], + description=''' + Fractional coordinates of the start and end point (in the basis of the reciprocal + lattice vectors) of the segment sampled in the $k$ space. The conventional symbols + (e.g., Gamma, K, L) of the same points are given in band_segm_labels + ''', + a_legacy=LegacyDefinition(name='band_segm_start_end')) + + number_of_k_points_per_segment = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $k$ points in the segment of the band structure, see + section_k_band_segment. + ''', + a_legacy=LegacyDefinition(name='number_of_k_points_per_segment')) + + +class BandGap(MSection): + ''' + This section stores information for a band gap within a band structure. + ''' + + m_def = Section( + aliases=['section_band_gap'], + validate=False, + a_legacy=LegacyDefinition(name='section_band_gap')) + + value = Quantity( + type=float, + shape=[], + unit='joule', + description=''' + Band gap energy. Value of zero corresponds to a band structure without a band gap. + ''', + a_legacy=LegacyDefinition(name='value')) + + type = Quantity( + type=MEnum('direct', 'indirect'), + shape=[], + description=''' + Type of band gap. + ''', + a_legacy=LegacyDefinition(name='type')) + + conduction_band_min_energy = Quantity( + type=float, + shape=[], + unit='joule', + description=''' + Conduction band minimum energy. + ''', + a_legacy=LegacyDefinition(name='conduction_band_min_energy')) + + valence_band_max_energy = Quantity( + type=float, + shape=[], + unit='joule', + description=''' + Valence band maximum energy. + ''', + a_legacy=LegacyDefinition(name='valence_band_max_energy')) + + conduction_band_min_k_point = Quantity( + type=np.dtype(np.float64), + shape=[3], + unit='1 / meter', + description=''' + Coordinate of the conduction band minimum in k-space. + ''', + a_legacy=LegacyDefinition(name='conduction_band_min_k_point')) + + valence_band_max_k_point = Quantity( + type=np.dtype(np.float64), + shape=[3], + unit='1 / meter', + description=''' + Coordinate of the valence band minimum in k-space. + ''', + a_legacy=LegacyDefinition(name='valence_band_max_k_point')) + + +class BrillouinZone(MSection): + ''' + Defines a polyhedra for the Brillouin zone in reciprocal space. + ''' + + m_def = Section( + aliases=['section_brillouin_zone'], + validate=False, + a_legacy=LegacyDefinition(name='section_brillouin_zone')) + + vertices = Quantity( + type=np.dtype(np.float64), + shape=[3, '1..*'], + description=''' + The vertices of the Brillouin zone corners as 3D coordinates in reciprocal space. + ''', + a_legacy=LegacyDefinition(name='vertices')) + + faces = Quantity( + type=np.dtype(np.int32), + shape=['1..*', '3..*'], + description=''' + The faces of the Brillouin zone polyhedron as vertex indices. The surface normal + is determined by a right-hand ordering of the points. + ''', + a_legacy=LegacyDefinition(name='faces')) + + +class KBand(MSection): + ''' + This section stores information on a $k$-band (electronic or vibrational band + structure) evaluation along one-dimensional pathways in the $k$ or $q$ (reciprocal) + space given in section_k_band_segment. Eigenvalues calculated at the actual $k$-mesh + used for energy_total evaluations, can be found in the section_eigenvalues section. + ''' + + m_def = Section( + aliases=['section_k_band'], + validate=False, + a_legacy=LegacyDefinition(name='section_k_band')) + + band_structure_kind = Quantity( + type=str, + shape=[], + description=''' + String to specify the kind of band structure (either electronic or vibrational). + ''', + a_legacy=LegacyDefinition(name='band_structure_kind')) + + reciprocal_cell = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='1 / meter', + description=''' + The reciprocal cell within which the band structure is calculated. + ''', + a_legacy=LegacyDefinition(name='reciprocal_cell')) + + is_standard_path = Quantity( + type=bool, + shape=[], + description=''' + Boolean indicating whether the path follows the standard path for this bravais + lattice. The AFLOW standard by Setyawan and Curtarolo is used + (https://doi.org/10.1016/j.commatsci.2010.05.010). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='is_standard_path')) + + brillouin_zone = SubSection( + sub_section=SectionProxy('BrillouinZone'), + repeats=False, + a_legacy=LegacyDefinition(name='brillouin_zone')) + + section_band_gap = SubSection( + sub_section=SectionProxy('BandGap'), + repeats=True, + description=''' + , Contains information for band gaps detected in the band structure. Contains a + section for each spin channel in the same order as reported for the band energies. + For channels without a band gap, a band gap value of zero is reported. + ''', + a_legacy=LegacyDefinition(name='section_band_gap')) + + section_k_band_segment = SubSection( + sub_section=SectionProxy('KBandSegment'), + repeats=True, + a_legacy=LegacyDefinition(name='section_k_band_segment')) + + +class MethodAtomKind(MSection): + ''' + Every section_method_atom_kind section contains method-related information about a + kind of atom, and is identified by one or more strings stored in + method_atom_kind_label. + + This categorization into atom kinds is more flexible than just atomic species, because + to different atoms of the same species different atom-centered basis sets or pseudo- + potentials may be assigned. For instance, if two different oxygen atoms are assigned + to different basis sets or pseudo-potentials, they have to distinguished into two + different *kinds* of O atoms, by creating two distinct section_method_atom_kind + sections. + ''' + + m_def = Section( + aliases=['section_method_atom_kind'], + validate=False, + a_legacy=LegacyDefinition(name='section_method_atom_kind')) + + method_atom_kind_atom_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Atomic number (number of protons) of this atom kind, use 0 if not an atom. + ''', + a_legacy=LegacyDefinition(name='method_atom_kind_atom_number')) + + method_atom_kind_explicit_electrons = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Number of explicit electrons (often called valence). + ''', + a_legacy=LegacyDefinition(name='method_atom_kind_explicit_electrons')) + + method_atom_kind_label = Quantity( + type=str, + shape=[], + description=''' + String used to identify the atoms of this kind. This should correspond to the + atom_labels of the configuration. It is possible for one atom kind to have + multiple labels (in order to allow two atoms of the same kind to have two + differently defined sets of atom-centered basis functions or two different pseudo- + potentials). Atom kind is typically the symbol of the atomic species but it can be + also a ghost or pseudo-atom. + ''', + a_legacy=LegacyDefinition(name='method_atom_kind_label')) + + method_atom_kind_mass = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='unified_atomic_mass_unit', + description=''' + Mass of the kind of this kind of atoms. + ''', + a_legacy=LegacyDefinition(name='method_atom_kind_mass')) + + method_atom_kind_pseudopotential_name = Quantity( + type=str, + shape=[], + description=''' + Name identifying the pseudopotential used. + ''', + a_legacy=LegacyDefinition(name='method_atom_kind_pseudopotential_name')) + + +class MethodToMethodRefs(MSection): + ''' + Section that describes the relationship between different section_method sections. For + instance, one calculation is a perturbation performed using a self-consistent field + (SCF) calculation as starting point, or a simulated system is partitioned in regions + with different but connected Hamiltonians (e.g., QM/MM, or a region treated via Kohn- + Sham DFT embedded into a region treated via orbital-free DFT). + + The kind of relationship between the method defined in this section and the referenced + one is described by method_to_method_kind. The referenced section section_method is + identified via method_to_method_ref (typically used for a section_method section in + the same section_run) or method_to_method_external_url. + ''' + + m_def = Section( + aliases=['section_method_to_method_refs'], + validate=False, + a_legacy=LegacyDefinition(name='section_method_to_method_refs')) + + method_to_method_external_url = Quantity( + type=str, + shape=[], + description=''' + URL used to reference an externally stored section_method. The kind of + relationship between the present and the referenced section_method is specified by + method_to_method_kind. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='method_to_method_external_url')) + + method_to_method_kind = Quantity( + type=str, + shape=[], + description=''' + String defining the kind of relationship that the referenced section_method has + with the present section_method. Valid values are described in the + [method_to_method_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- + meta-info/wikis/metainfo/method-to-method-kind). Often calculations are connected, + for instance, one calculation is a perturbation performed using a self-consistent + field (SCF) calculation as starting point, or a simulated system is partitioned in + regions with different but connected Hamiltonians (e.g., QM/MM, or a region + treated via Kohn-Sham DFT embedded into a region treated via orbital-free DFT). + Hence, the need of keeping track of these connected calculations. The referenced + section_method is identified via method_to_method_ref (typically used for a + section_method in the same section_run) or method_to_method_external_url. + ''', + a_legacy=LegacyDefinition(name='method_to_method_kind')) + + method_to_method_ref = Quantity( + type=Reference(SectionProxy('Method')), + shape=[], + description=''' + Reference to a local section_method. If both method_to_method_ref and + method_to_method_external_url are given, then method_to_method_ref is a local copy + of the value contained in method_to_method_external_url. The kind of relationship + between the method defined in the present section_method and the referenced one is + described by method_to_method_kind. + ''', + a_legacy=LegacyDefinition(name='method_to_method_ref')) + + +class Method(MSection): + ''' + Section containing the various parameters that define the theory and the + approximations (convergence, thresholds,...) to perform a *single configuration + calculation*, see section_single_configuration_calculation. + + *NOTE*: This section does not contain settings for molecular dynamics, geometry + optimization etc. See section frame_sequence for these other settings instead. + ''' + + m_def = Section( + aliases=['section_method'], + validate=False, + a_legacy=LegacyDefinition(name='section_method')) + + basis_set = Quantity( + type=str, + shape=[], + description=''' + Unique string identifying the basis set used for the final wavefunctions + calculated with XC_method. It might identify a class of basis sets, often matches + one of the strings given in any of basis_set_name. + ''', + categories=[SettingsNumericalParameter, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='basis_set')) + + calculation_method_current = Quantity( + type=str, + shape=[], + description=''' + String that represents the method used to calculate the energy_current. If the + method is perturbative, this string does not describe the starting point method, + the latter being referenced to by section_method_to_method_refs. For self- + consistent field (SCF) ab initio calculations, for example, this is composed by + concatenating XC_method_current and basis_set. See [calculation_method_current + wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/calculation-method-current) for the details. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='calculation_method_current')) + + calculation_method_kind = Quantity( + type=str, + shape=[], + description=''' + Kind of method in calculation_method_current. + + Accepted values are: + + - absolute + + - perturbative. + ''', + a_legacy=LegacyDefinition(name='calculation_method_kind')) + + calculation_method = Quantity( + type=str, + shape=[], + description=''' + String that uniquely represents the method used to calculate energy_total, If the + present calculation_method_current is a perturbative method Y that uses method X + as starting point, this string is automatically created as X@Y, where X is taken + from calculation_method_current and Y from method_to_method_ref. In order to + activate this, method_to_method_kind must have the value starting_point (see the + [method_to_method_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- + meta-info/wikis/metainfo/method-to-method-kind)). + ''', + a_legacy=LegacyDefinition(name='calculation_method')) + + electronic_structure_method = Quantity( + type=str, + shape=[], + description=''' + Non-unique string identifying the used electronic structure method. It is not + unique in the sense that two calculations with the same + electronic_structure_method string may have not been performed with exactly the + same method. The allowed strings are given in the [electronic structure method + wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/electronic-structure-method). + ''', + categories=[SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='electronic_structure_method')) + + k_mesh_points = Quantity( + type=np.dtype(np.float64), + shape=['number_of_k_mesh_points', 3], + description=''' + List of all the k points in the $k$-point mesh. These are the k point used to + evaluate energy_total, and are in fractional coordinates (in the basis of the + reciprocal-lattice vectors). + ''', + categories=[SettingsKPoints, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='k_mesh_points')) + + k_mesh_weights = Quantity( + type=np.dtype(np.float64), + shape=['number_of_k_mesh_points'], + description=''' + Weights of all the k points in the $k$-point mesh. These are the weights for + k_mesh_points (i.e. the k point used to evaluate energy_total). + ''', + categories=[SettingsKPoints, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='k_mesh_weights')) + + number_of_k_mesh_points = Quantity( + type=int, + shape=[], + description=''' + number of k points in the mesh (i.e. the k points used to evaluate energy_total). + ''', + categories=[SettingsKPoints, SettingsPotentialEnergySurface, Unused], + a_legacy=LegacyDefinition(name='number_of_k_mesh_points')) + + number_of_spin_channels = Quantity( + type=int, + shape=[], + description=''' + Gives the number of spin channels, see section_method. + ''', + a_legacy=LegacyDefinition(name='number_of_spin_channels')) + + relativity_method = Quantity( + type=str, + shape=[], + description=''' + Describes the relativistic treatment used for the calculation of the final energy + and related quantities. If skipped or empty, no relativistic treatment is applied. + ''', + categories=[SettingsRelativity, SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='relativity_method')) + + scf_max_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Specifies the maximum number of allowed self-consistent field (SCF) iterations in + a calculation run, see section_run. + ''', + categories=[SettingsScf], + a_legacy=LegacyDefinition(name='scf_max_iteration')) + + scf_threshold_energy_change = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Specifies the threshold for the energy_total_scf_iteration change between two + subsequent self-consistent field (SCF) iterations. The SCF is considered converged + when the total-energy change between two SCF cycles is below the threshold + (possibly in combination with other criteria). + ''', + categories=[SettingsScf], + a_legacy=LegacyDefinition(name='scf_threshold_energy_change')) + + self_interaction_correction_method = Quantity( + type=str, + shape=[], + description=''' + Contains the name for the self-interaction correction (SIC) treatment used to + calculate the final energy and related quantities. If skipped or empty, no special + correction is applied. + + The following SIC methods are available: + + | SIC method | Description | + + | ------------------------- | -------------------------------- | + + | `""` | No correction | + + | `"SIC_AD"` | The average density correction | + + | `"SIC_SOSEX"` | Second order screened exchange | + + | `"SIC_EXPLICIT_ORBITALS"` | (scaled) Perdew-Zunger correction explicitly on a + set of orbitals | + + | `"SIC_MAURI_SPZ"` | (scaled) Perdew-Zunger expression on the spin + density / doublet unpaired orbital | + + | `"SIC_MAURI_US"` | A (scaled) correction proposed by Mauri and co- + workers on the spin density / doublet unpaired orbital | + ''', + categories=[SettingsSelfInteractionCorrection, SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='self_interaction_correction_method')) + + smearing_kind = Quantity( + type=str, + shape=[], + description=''' + Specifies the kind of smearing on the electron occupation used to calculate the + free energy (see energy_free) + + Valid values are: + + | Smearing kind | Description | + + | ------------------------- | --------------------------------- | + + | `"empty"` | No smearing is applied | + + | `"gaussian"` | Gaussian smearing | + + | `"fermi"` | Fermi smearing | + + | `"marzari-vanderbilt"` | Marzari-Vanderbilt smearing | + + | `"methfessel-paxton"` | Methfessel-Paxton smearing | + + | `"tetrahedra"` | Interpolation of state energies and occupations + (ignores smearing_width) | + ''', + categories=[SettingsSmearing], + a_legacy=LegacyDefinition(name='smearing_kind')) + + smearing_width = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Specifies the width of the smearing in energy for the electron occupation used to + calculate the free energy (see energy_free). + + *NOTE:* Not all methods specified in smearing_kind uses this value. + ''', + categories=[SettingsSmearing], + a_legacy=LegacyDefinition(name='smearing_width')) + + spin_target_multiplicity = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Stores the target (user-imposed) value of the spin multiplicity $M=2S+1$, where + $S$ is the total spin. It is an integer number. This value is not necessarily the + value obtained at the end of the calculation. See spin_S2 for the converged value + of the spin moment. + ''', + a_legacy=LegacyDefinition(name='spin_target_multiplicity')) + + stress_tensor_method = Quantity( + type=str, + shape=[], + description=''' + Specifies the method used to calculate stress_tensor for, e.g., molecular dynamics + and geometry optimization. + + The allowed values are: + + * numeric + + * analytic + ''', + categories=[SettingsStressTensor], + a_legacy=LegacyDefinition(name='stress_tensor_method')) + + total_charge = Quantity( + type=np.dtype(np.int32), + shape=[], + unit='coulomb', + description=''' + Provides the total amount of charge of the system in a run. + ''', + a_legacy=LegacyDefinition(name='total_charge')) + + van_der_Waals_method = Quantity( + type=str, + shape=[], + description=''' + Describes the Van der Waals method. If skipped or an empty string is used, it + means no Van der Waals correction is applied. + + Allowed values are: + + | Van der Waals method | Description | + + | --------------------- | ----------------------------------------- | + + | `""` | No Van der Waals correction | + + | `"TS"` | A. Tkatchenko and M. Scheffler, [Phys. Rev. Lett. + **102**, 073005 (2009)](http://dx.doi.org/10.1103/PhysRevLett.102.073005) | + + | `"OBS"` | F. Ortmann, F. Bechstedt, and W. G. Schmidt, [Phys. Rev. + B **73**, 205101 (2006)](http://dx.doi.org/10.1103/PhysRevB.73.205101) | + + | `"G06"` | S. Grimme, [J. Comput. Chem. **27**, 1787 + (2006)](http://dx.doi.org/10.1002/jcc.20495) | + + | `"JCHS"` | P. Jurečka, J. Černý, P. Hobza, and D. R. Salahub, + [Journal of Computational Chemistry **28**, 555 + (2007)](http://dx.doi.org/10.1002/jcc.20570) | + + | `"MDB"` | Many-body dispersion. A. Tkatchenko, R. A. Di Stasio Jr, + R. Car, and M. Scheffler, [Physical Review Letters **108**, 236402 + (2012)](http://dx.doi.org/10.1103/PhysRevLett.108.236402) and A. Ambrosetti, A. M. + Reilly, R. A. Di Stasio Jr, and A. Tkatchenko, [The Journal of Chemical Physics + **140**, 18A508 (2014)](http://dx.doi.org/10.1063/1.4865104) | + + | `"XC"` | The method to calculate the Van der Waals energy uses a + non-local functional which is described in section_XC_functionals. | + ''', + categories=[SettingsVanDerWaals, SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='van_der_Waals_method')) + + XC_functional = Quantity( + type=str, + shape=[], + description=''' + This value describes a DFT exchange-correlation (XC) functional used for + evaluating the energy value stored in energy_XC_functional and related quantities + (e.g., forces). + + It is a unique short name obtained by combining the data stored in + section_XC_functionals, more specifically by combining different + XC_functional_name as described in the [XC_functional wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- + functional). + ''', + categories=[SettingsPotentialEnergySurface, SettingsPhysicalParameter, SettingsXCFunctional, SettingsXC], + a_legacy=LegacyDefinition(name='XC_functional')) + + XC_method = Quantity( + type=str, + shape=[], + description=''' + Describes the exchange correlation (XC) method used for evaluating the XC energy + (energy_XC). Differently from XC_functional, perturbative treatments are also + accounted for, where the string contains the reference to both the perturbative + (e.g., MP2) and the starting point (e.g, Hartree-Fock) XC method defined in the + section section_method. + + The value consists of XC_method_current concatenated with the `@` character and + the XC method (XC_method) defined in section_method that is referred to by + method_to_method_ref where method_to_method_kind = "starting_point_method". + ''', + categories=[SettingsXC, SettingsPotentialEnergySurface, Unused], + a_legacy=LegacyDefinition(name='XC_method')) + + XC_method_current = Quantity( + type=str, + shape=[], + description=''' + Identifies the exchange correlation (XC) method used for energy_XC and related + quantities in a standardized short form as a string. + + It is built by joining the values in the following order using the underscore `_` + character: electronic_structure_method, XC_functional, + self_interaction_correction_method, van_der_Waals_method and relativity_method. + + If any of the methods listed in the string contain non-standard settings, then the + first 10 characters of the Base64 URL encoding of SHA 512 checksum of a normalized + JSON with all non-redundant non-derived settings_XC are appended to the the string + preceded by an underscore. + + With empty strings, the underscore `_` character is skipped. + + If the method defined in the section_method section is perturbative, the + XC_method_current contains only the perturbative method, not the starting point + (e.g. the DFT XC functional used as a starting point for a RPA perturbative + calculation). In this case, the string that contains both the perturbative and + starting point method is stored in XC_method. + ''', + categories=[SettingsXC, SettingsPotentialEnergySurface], + a_legacy=LegacyDefinition(name='XC_method_current')) + + dft_plus_u_functional = Quantity( + type=str, + shape=[], + description=''' + Type of DFT+U functional (such as DFT/DFT+U double-counting compensation). Valid + names are described in the [dft\\_plus\\_u\\_functional wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/dft- + plus-u-functional). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='dft_plus_u_functional')) + + dft_plus_u_projection_type = Quantity( + type=str, + shape=[], + description=''' + DFT+U: Type of orbitals used for projection in order to calculate occupation + numbers. Valid names are described in the [dft\\_plus\\_u\\_projection\\_type wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/dft- + plus-u-projection-type). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='dft_plus_u_projection_type')) + + gw_bare_coulomb_cutofftype = Quantity( + type=str, + shape=[], + description=''' + Cutoff type for the calculation of the bare Coulomb potential: none, 0d, 1d, 2d. + See Rozzi et al., PRB 73, 205119 (2006) + ''', + a_legacy=LegacyDefinition(name='gw_bare_coulomb_cutofftype')) + + gw_bare_coulomb_gmax = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='1 / meter', + description=''' + Maximum G for the pw basis for the Coulomb potential. + ''', + a_legacy=LegacyDefinition(name='gw_bare_coulomb_gmax')) + + gw_basis_set = Quantity( + type=str, + shape=[], + description=''' + Auxillary basis set used for non-local operators: mixed - mixed basis set, Kotani + and Schilfgaarde, Solid State Comm. 121, 461 (2002). + ''', + a_legacy=LegacyDefinition(name='gw_basis_set')) + + gw_core_treatment = Quantity( + type=str, + shape=[], + description=''' + It specifies whether the core states are treated in the GW calculation: all - All + electron calculation; val - Valence electron only calculation; vab - Core + electrons are excluded from the mixed product basis; xal - All electron treatment + of the exchange self-energy only + ''', + a_legacy=LegacyDefinition(name='gw_core_treatment')) + + gw_frequency_grid_type = Quantity( + type=str, + shape=[], + description=''' + Frequency integration grid type for the correlational self energy: 'eqdis' - + equidistant frequencies from 0 to freqmax; 'gaulag' - Gauss-Laguerre quadrature + from 0 to infinity; 'gauleg' - Gauss-Legendre quadrature from 0 to freqmax; + 'gaule2' (default) - double Gauss-Legendre quadrature from 0 to freqmax and from + freqmax to infinity. + ''', + a_legacy=LegacyDefinition(name='gw_frequency_grid_type')) + + gw_max_frequency = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Maximum frequency for the calculation of the self energy. + ''', + a_legacy=LegacyDefinition(name='gw_max_frequency')) + + gw_mixed_basis_gmax = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='1 / meter', + description=''' + Cut-off parameter for the truncation of the expansion of the plane waves in the + interstitial region. + ''', + a_legacy=LegacyDefinition(name='gw_mixed_basis_gmax')) + + gw_mixed_basis_lmax = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Maximum l value used for the radial functions within the muffin-tin. + ''', + a_legacy=LegacyDefinition(name='gw_mixed_basis_lmax')) + + gw_mixed_basis_tolerance = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Eigenvalue threshold below which the egenvectors are discarded in the construction + of the radial basis set. + ''', + a_legacy=LegacyDefinition(name='gw_mixed_basis_tolerance')) + + gw_ngridq = Quantity( + type=np.dtype(np.int32), + shape=[3], + description=''' + k/q-point grid size used in the GW calculation. + ''', + a_legacy=LegacyDefinition(name='gw_ngridq')) + + gw_frequency_number = Quantity( + type=np.dtype(np.int32), + shape=['gw_number_of_frequencies'], + description=''' + Number referring to the frequency used in the calculation of the self energy. + ''', + a_legacy=LegacyDefinition(name='gw_frequency_number')) + + gw_frequency_values = Quantity( + type=np.dtype(np.float64), + shape=['gw_number_of_frequencies'], + unit='joule', + description=''' + Values of the frequency used in the calculation of the self energy. + ''', + a_legacy=LegacyDefinition(name='gw_frequency_values')) + + gw_frequency_weights = Quantity( + type=np.dtype(np.float64), + shape=['gw_number_of_frequencies'], + description=''' + Weights of the frequency used in the calculation of the self energy. + ''', + a_legacy=LegacyDefinition(name='gw_frequency_weights')) + + gw_number_of_frequencies = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Number of frequency points used in the calculation of the self energy. + ''', + a_legacy=LegacyDefinition(name='gw_number_of_frequencies')) + + gw_polarizability_number_of_empty_states = Quantity( + type=int, + shape=[], + description=''' + Number of empty states used to compute the polarizability P + ''', + a_legacy=LegacyDefinition(name='gw_polarizability_number_of_empty_states')) + + gw_qp_equation_treatment = Quantity( + type=str, + shape=[], + description=''' + Methods to solve the quasi-particle equation: 'linearization', 'self-consistent' + ''', + a_legacy=LegacyDefinition(name='gw_qp_equation_treatment')) + + gw_screened_coulomb_volume_average = Quantity( + type=str, + shape=[], + description=''' + Type of volume averaging for the dynamically screened Coulomb potential: isotropic + - Simple averaging along a specified direction using only diagonal components of + the dielectric tensor; anisotropic - Anisotropic screening by C. Freysoldt et al., + CPC 176, 1-13 (2007) + ''', + a_legacy=LegacyDefinition(name='gw_screened_coulomb_volume_average')) + + gw_screened_Coulomb = Quantity( + type=str, + shape=[], + description=''' + Model used to calculate the dinamically-screened Coulomb potential: 'rpa' - Full- + frequency random-phase approximation; 'ppm' - Godby-Needs plasmon-pole model Godby + and Needs, Phys. Rev. Lett. 62, 1169 (1989); 'ppm_hl' - Hybertsen and Louie, Phys. + Rev. B 34, 5390 (1986); 'ppm_lh' - von der Linden and P. Horsh, Phys. Rev. B 37, + 8351 (1988); 'ppm_fe' - Farid and Engel, Phys. Rev. B 47,15931 (1993); 'cdm' - + Contour deformation method, Phys. Rev. B 67, 155208 (2003).) + ''', + a_legacy=LegacyDefinition(name='gw_screened_Coulomb')) + + gw_self_energy_c_analytical_continuation = Quantity( + type=str, + shape=[], + description=''' + Models for the correlation self-energy analytical continuation: 'pade' - Pade's + approximant (by H. J. Vidberg and J. W. Serence, J. Low Temp. Phys. 29, 179 + (1977)); 'mpf' - Multi-Pole Fitting (by H. N Rojas, R. W. Godby and R. J. Needs, + Phys. Rev. Lett. 74, 1827 (1995)); 'cd' - contour deformation; 'ra' - real axis + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_c_analytical_continuation')) + + gw_self_energy_c_number_of_empty_states = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Number of empty states to be used to calculate the correlation self energy. + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_c_number_of_empty_states')) + + gw_self_energy_c_number_of_poles = Quantity( + type=int, + shape=[], + description=''' + Number of poles used in the analytical continuation. + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_c_number_of_poles')) + + gw_self_energy_singularity_treatment = Quantity( + type=str, + shape=[], + description=''' + Treatment of the integrable singular terms in the calculation of the self energy. + Values: 'mpb' - Auxiliary function method by S. Massidda, M. Posternak, and A. + Baldereschi, PRB 48, 5058 (1993); 'crg' - Auxiliary function method by P. Carrier, + S. Rohra, and A. Goerling, PRB 75, 205126 (2007). + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_singularity_treatment')) + + gw_starting_point = Quantity( + type=str, + shape=[], + description=''' + Exchange-correlation functional of the ground-state calculation. See XC_functional + list at https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- + functional + ''', + a_legacy=LegacyDefinition(name='gw_starting_point')) + + gw_type_test = Quantity( + type=str, + shape=[], + description=''' + GW methodology: exciting test variable + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='gw_type_test')) + + gw_type = Quantity( + type=str, + shape=[], + description=''' + GW methodology: G0W0; ev-scGW: (eigenvalues self-consistent GW) – Phys.Rev.B 34, + 5390 (1986); qp-scGW: (quasi-particle self-consistent GW) – Phys. Rev. Lett. 96, + 226402 (2006) scGW0: (self-consistent G with fixed W0) – Phys.Rev.B 54, 8411 + (1996); scG0W: (self-consistent W with fixed G0); scGW: (self-consistent GW) – + Phys. Rev. B 88, 075105 (2013) + ''', + a_legacy=LegacyDefinition(name='gw_type')) + + method_to_topology_ref = Quantity( + type=Reference(SectionProxy('Topology')), + shape=[], + description=''' + Reference to the topology and force fields to be used. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='method_to_topology_ref')) + + section_method_atom_kind = SubSection( + sub_section=SectionProxy('MethodAtomKind'), + repeats=True, + a_legacy=LegacyDefinition(name='section_method_atom_kind')) + + section_method_to_method_refs = SubSection( + sub_section=SectionProxy('MethodToMethodRefs'), + repeats=True, + a_legacy=LegacyDefinition(name='section_method_to_method_refs')) + + section_XC_functionals = SubSection( + sub_section=SectionProxy('XCFunctionals'), + repeats=True, + a_legacy=LegacyDefinition(name='section_XC_functionals')) + + section_dft_plus_u_orbital = SubSection( + sub_section=SectionProxy('DftPlusUOrbital'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_dft_plus_u_orbital')) + + section_method_basis_set = SubSection( + sub_section=SectionProxy('MethodBasisSet'), + repeats=True, + a_legacy=LegacyDefinition(name='section_method_basis_set')) + + +class OriginalSystem(MSection): + ''' + Section containing symmetry information that is specific to the original system. + ''' + + m_def = Section( + aliases=['section_original_system'], + validate=False, + a_legacy=LegacyDefinition(name='section_original_system')) + + equivalent_atoms_original = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms'], + description=''' + Gives a mapping table of atoms to symmetrically independent atoms in the original + cell. This is used to find symmetrically equivalent atoms. + ''', + a_legacy=LegacyDefinition(name='equivalent_atoms_original')) + + wyckoff_letters_original = Quantity( + type=str, + shape=['number_of_atoms'], + description=''' + Wyckoff letters for atoms in the original cell. + ''', + a_legacy=LegacyDefinition(name='wyckoff_letters_original')) + + +class PrimitiveSystem(MSection): + ''' + Section containing symmetry information that is specific to the primitive system. The + primitive system is derived from the standardized system with a transformation that is + specific to the centring. The transformation matrices can be found e.g. from here: + https://atztogo.github.io/spglib/definition.html#transformation-to-the-primitive-cell + ''' + + m_def = Section( + aliases=['section_primitive_system'], + validate=False, + a_legacy=LegacyDefinition(name='section_primitive_system')) + + atom_positions_primitive = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms_primitive', 3], + description=''' + Atom positions in the primitive cell in reduced units. + ''', + a_legacy=LegacyDefinition(name='atom_positions_primitive')) + + atomic_numbers_primitive = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms_primitive'], + description=''' + Atomic numbers in the primitive cell. + ''', + a_legacy=LegacyDefinition(name='atomic_numbers_primitive')) + + equivalent_atoms_primitive = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms_primitive'], + description=''' + Gives a mapping table of atoms to symmetrically independent atoms in the primitive + cell. This is used to find symmetrically equivalent atoms. + ''', + a_legacy=LegacyDefinition(name='equivalent_atoms_primitive')) + + lattice_vectors_primitive = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='meter', + description=''' + Primitive lattice vectors. The vectors are the rows of this matrix. + ''', + a_legacy=LegacyDefinition(name='lattice_vectors_primitive')) + + number_of_atoms_primitive = Quantity( + type=int, + shape=[], + description=''' + Number of atoms in primitive system. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_atoms_primitive')) + + wyckoff_letters_primitive = Quantity( + type=str, + shape=['number_of_atoms_primitive'], + description=''' + Wyckoff letters for atoms in the primitive cell. + ''', + a_legacy=LegacyDefinition(name='wyckoff_letters_primitive')) + + +class ProcessorInfo(MSection): + ''' + Section with information about a processor that generated or added information to the + current calculation. + ''' + + m_def = Section( + aliases=['section_processor_info'], + validate=False, + a_legacy=LegacyDefinition(name='section_processor_info')) + + processor_id = Quantity( + type=str, + shape=[], + description=''' + Id (name+version) of the processor that generated or added information to the + current calculation. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='processor_id')) + + processor_number_of_evaluated_contexts = Quantity( + type=np.dtype(np.int64), + shape=[], + description=''' + number of contexts evaluated with this processor in the current current + calculation. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='processor_number_of_evaluated_contexts')) + + processor_number_of_failed_contexts = Quantity( + type=np.dtype(np.int64), + shape=[], + description=''' + number of contexts in the current current calculation that had failure for this + processor. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='processor_number_of_failed_contexts')) + + processor_number_of_skipped_contexts = Quantity( + type=np.dtype(np.int64), + shape=[], + description=''' + number of contexts skipped by this processor in the current current calculation. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='processor_number_of_skipped_contexts')) + + processor_number_of_successful_contexts = Quantity( + type=np.dtype(np.int64), + shape=[], + description=''' + number of contexts in the current calculation that where successfully handled by + this processor. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='processor_number_of_successful_contexts')) + + processor_version_details = Quantity( + type=typing.Any, + shape=[], + description=''' + detailed version information on the processor that generated or added information + to the current calculation. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='processor_version_details')) + + +class ProcessorLogEvent(MSection): + ''' + A log event + ''' + + m_def = Section( + aliases=['section_processor_log_event'], + validate=False, + a_legacy=LegacyDefinition(name='section_processor_log_event')) + + processor_log_event_level = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Level of the logging, a lower number has more priority. The levels are the same as + log4j: FATAL -> 100, ERROR -> 200, WARN -> 300, INFO -> 400, DEBUG -> 500, TRACE + -> 600 + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='processor_log_event_level')) + + processor_log_event_message = Quantity( + type=str, + shape=[], + description=''' + The log message + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='processor_log_event_message')) + + +class ProcessorLog(MSection): + ''' + log of a processor + ''' + + m_def = Section( + aliases=['section_processor_log'], + validate=False, + a_legacy=LegacyDefinition(name='section_processor_log')) + + processor_log_processor_id = Quantity( + type=str, + shape=[], + description=''' + The processor id of the processor creating this log + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='processor_log_processor_id')) + + processor_log_start = Quantity( + type=str, + shape=[], + description=''' + Start of the log (in ansi notation YYYY-MM-TT...) + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='processor_log_start')) + + section_processor_log_event = SubSection( + sub_section=SectionProxy('ProcessorLogEvent'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_processor_log_event')) + + +class Prototype(MSection): + ''' + Information on the prototype corresponding to the current section. + ''' + + m_def = Section( + aliases=['section_prototype'], + validate=False, + a_legacy=LegacyDefinition(name='section_prototype')) + + prototype_aflow_id = Quantity( + type=str, + shape=[], + description=''' + AFLOW id of the prototype (see + http://aflowlib.org/CrystalDatabase/prototype_index.html) identified on the basis + of the space_group and normalized_wyckoff. + ''', + a_legacy=LegacyDefinition(name='prototype_aflow_id')) + + prototype_aflow_url = Quantity( + type=str, + shape=[], + description=''' + Url to the AFLOW definition of the prototype (see + http://aflowlib.org/CrystalDatabase/prototype_index.html) identified on the basis + of the space_group and normalized_wyckoff. + ''', + a_legacy=LegacyDefinition(name='prototype_aflow_url')) + + prototype_assignment_method = Quantity( + type=str, + shape=[], + description=''' + Method used to identify the prototype. + ''', + a_legacy=LegacyDefinition(name='prototype_assignment_method')) + + prototype_label = Quantity( + type=str, + shape=[], + description=''' + Label of the prototype identified on the basis of the space_group and + normalized_wyckoff. The label is in the same format as in the read_prototypes + function: --). + ''', + a_legacy=LegacyDefinition(name='prototype_label')) + + +class Run(MSection): + ''' + Every section_run represents a single call of a program. What exactly is contained in + a run depends on the run type (see for example section_method and + section_single_configuration_calculation) and the program (see [program_info + ](program_info)). + ''' + + m_def = Section( + aliases=['section_run'], + validate=False, + a_legacy=LegacyDefinition(name='section_run')) + + calculation_file_uri = Quantity( + type=str, + shape=[], + description=''' + Contains the nomad uri of a raw the data file connected to the current run. There + should be an value for the main_file_uri and all ancillary files. + ''', + a_legacy=LegacyDefinition(name='calculation_file_uri')) + + message_debug_run = Quantity( + type=str, + shape=[], + description=''' + A debugging message of the computational program, associated with a run. + ''', + categories=[MessageDebug, Unused], + a_legacy=LegacyDefinition(name='message_debug_run')) + + message_error_run = Quantity( + type=str, + shape=[], + description=''' + An error message of the computational program, associated with a run. + ''', + categories=[MessageInfo, MessageDebug, MessageError, MessageWarning, Unused], + a_legacy=LegacyDefinition(name='message_error_run')) + + message_info_run = Quantity( + type=str, + shape=[], + description=''' + An information message of the computational program, associated with a run. + ''', + categories=[MessageInfo, MessageDebug, Unused], + a_legacy=LegacyDefinition(name='message_info_run')) + + message_warning_run = Quantity( + type=str, + shape=[], + description=''' + A warning message of the computational program, associated with a run. + ''', + categories=[MessageInfo, MessageDebug, MessageWarning, Unused], + a_legacy=LegacyDefinition(name='message_warning_run')) + + parsing_message_debug_run = Quantity( + type=str, + shape=[], + description=''' + This field is used for debugging messages of the parsing program associated with a + single configuration calculation, see section_single_configuration_calculation. + ''', + categories=[ParsingMessageDebug, Unused], + a_legacy=LegacyDefinition(name='parsing_message_debug_run')) + + parsing_message_error_run = Quantity( + type=str, + shape=[], + description=''' + This field is used for error messages of the parsing program associated with a + run, see section_run. + ''', + categories=[ParsingMessageInfo, ParsingMessageError, ParsingMessageWarning, ParsingMessageDebug, Unused], + a_legacy=LegacyDefinition(name='parsing_message_error_run')) + + parsing_message_info_run = Quantity( + type=str, + shape=[], + description=''' + This field is used for info messages of the parsing program associated with a run, + see section_run. + ''', + categories=[ParsingMessageInfo, ParsingMessageDebug, Unused], + a_legacy=LegacyDefinition(name='parsing_message_info_run')) + + parsing_message_warning_run = Quantity( + type=str, + shape=[], + description=''' + This field is used for warning messages of the parsing program associated with a + run, see section_run. + ''', + categories=[ParsingMessageInfo, ParsingMessageWarning, ParsingMessageDebug], + a_legacy=LegacyDefinition(name='parsing_message_warning_run')) + + program_basis_set_type = Quantity( + type=str, + shape=[], + description=''' + The type of basis set used by the program to represent wave functions. Valid + values are: [`Numeric AOs`, `Gaussians`, `(L)APW+lo`, `plane waves`, `psinc + functions`, `real-space grid`]. + ''', + a_legacy=LegacyDefinition(name='program_basis_set_type')) + + program_compilation_datetime = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Contains the program compilation date and time from *Unix epoch* (00:00:00 UTC on + 1 January 1970) in seconds. For date and times without a timezone, the default + timezone GMT is used. + ''', + categories=[AccessoryInfo, ProgramInfo], + a_legacy=LegacyDefinition(name='program_compilation_datetime')) + + program_compilation_host = Quantity( + type=str, + shape=[], + description=''' + Specifies the host on which the program was compiled. + ''', + categories=[AccessoryInfo, ProgramInfo], + a_legacy=LegacyDefinition(name='program_compilation_host')) + + program_name = Quantity( + type=str, + shape=[], + description=''' + Specifies the name of the program that generated the data. + ''', + categories=[AccessoryInfo, ProgramInfo], + a_legacy=LegacyDefinition(name='program_name')) + + program_version = Quantity( + type=str, + shape=[], + description=''' + Specifies the version of the program that was used. This should be the version + number of an official release, the version tag or a commit id as well as the + location of the repository. + ''', + categories=[AccessoryInfo, ProgramInfo], + a_legacy=LegacyDefinition(name='program_version')) + + run_clean_end = Quantity( + type=bool, + shape=[], + description=''' + Indicates whether this run terminated properly (true), or if it was killed or + exited with an error code unequal to zero (false). + ''', + a_legacy=LegacyDefinition(name='run_clean_end')) + + run_hosts = Quantity( + type=typing.Any, + shape=[], + description=''' + An associative list of host(s) that performed this simulation. This is an + associative list that contains program-dependent information (*key*) on how the + host was used (*value*). Useful for debugging purposes. + ''', + categories=[ParallelizationInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='run_hosts')) + + raw_id = Quantity( + type=str, + shape=[], + description=''' + An optional calculation id, if one is found in the code input/output files. + ''', + a_legacy=LegacyDefinition(name='raw_id')) + + time_run_cpu1_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end time of the run on CPU 1. + ''', + categories=[TimeInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='time_run_cpu1_end')) + + time_run_cpu1_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start time of the run on CPU 1. + ''', + categories=[TimeInfo, AccessoryInfo], + a_legacy=LegacyDefinition(name='time_run_cpu1_start')) + + time_run_date_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end date of the run as time since the *Unix epoch* (00:00:00 UTC on 1 + January 1970) in seconds. For date and times without a timezone, the default + timezone GMT is used. + ''', + categories=[TimeInfo, AccessoryInfo], + a_legacy=LegacyDefinition(name='time_run_date_end')) + + time_run_date_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start date of the run as time since the *Unix epoch* (00:00:00 UTC on 1 + January 1970) in seconds. For date and times without a timezone, the default + timezone GMT is used. + ''', + categories=[TimeInfo, AccessoryInfo], + a_legacy=LegacyDefinition(name='time_run_date_start')) + + time_run_wall_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time at the end of the run. + ''', + categories=[TimeInfo, AccessoryInfo], + a_legacy=LegacyDefinition(name='time_run_wall_end')) + + time_run_wall_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time from the start of the run. + ''', + categories=[TimeInfo, AccessoryInfo], + a_legacy=LegacyDefinition(name='time_run_wall_start')) + + section_basis_set_atom_centered = SubSection( + sub_section=SectionProxy('BasisSetAtomCentered'), + repeats=True, + a_legacy=LegacyDefinition(name='section_basis_set_atom_centered')) + + section_basis_set_cell_dependent = SubSection( + sub_section=SectionProxy('BasisSetCellDependent'), + repeats=True, + a_legacy=LegacyDefinition(name='section_basis_set_cell_dependent')) + + section_frame_sequence = SubSection( + sub_section=SectionProxy('FrameSequence'), + repeats=True, + a_legacy=LegacyDefinition(name='section_frame_sequence')) + + section_method = SubSection( + sub_section=SectionProxy('Method'), + repeats=True, + a_legacy=LegacyDefinition(name='section_method')) + + section_sampling_method = SubSection( + sub_section=SectionProxy('SamplingMethod'), + repeats=True, + a_legacy=LegacyDefinition(name='section_sampling_method')) + + section_single_configuration_calculation = SubSection( + sub_section=SectionProxy('SingleConfigurationCalculation'), + repeats=True, + a_legacy=LegacyDefinition(name='section_single_configuration_calculation')) + + section_system = SubSection( + sub_section=SectionProxy('System'), + repeats=True, + a_legacy=LegacyDefinition(name='section_system')) + + section_topology = SubSection( + sub_section=SectionProxy('Topology'), + repeats=True, + a_legacy=LegacyDefinition(name='section_topology')) + + +class SamplingMethod(MSection): + ''' + Section containing the settings describing a (potential-energy surface) sampling + method. + + Results and monitored quantities of such sampling are collected in a sequence of + frames, section_frame_sequence. + ''' + + m_def = Section( + aliases=['section_sampling_method'], + validate=False, + a_legacy=LegacyDefinition(name='section_sampling_method')) + + ensemble_type = Quantity( + type=str, + shape=[], + description=''' + Kind of sampled ensemble stored in section_frame_sequence; valid values are + defined in [ensemble_type wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- + meta-info/wikis/metainfo/ensemble-type). + ''', + a_legacy=LegacyDefinition(name='ensemble_type')) + + geometry_optimization_energy_change = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of threshold for the energy_total change between two geometry optimization + steps, as convergence criterion of the geometry_optimization_method. A geometry + optimization is considered converged when the energy_total change between two + geometry optimization steps is below the threshold (possibly in combination with + other criteria) + ''', + categories=[SettingsGeometryOptimization, SettingsSampling], + a_legacy=LegacyDefinition(name='geometry_optimization_energy_change')) + + geometry_optimization_geometry_change = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='meter', + description=''' + Value of threshold for the displacement of the nuclei between two geometry + optimization steps as convergence criterion of the geometry_optimization_method. A + geometry optimization is considered converged when the maximum among the + displacements of the nuclei between two geometry optimization steps is below the + threshold (possibly in combination with other criteria) + ''', + categories=[SettingsGeometryOptimization, SettingsSampling], + a_legacy=LegacyDefinition(name='geometry_optimization_geometry_change')) + + geometry_optimization_method = Quantity( + type=str, + shape=[], + description=''' + Algorithm for the geometry optimization. Allowed values are listed in the + [geometry_optimization_method wiki page](https://gitlab.mpcdf.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/geometry-optimization-method). + ''', + categories=[SettingsGeometryOptimization, SettingsSampling], + a_legacy=LegacyDefinition(name='geometry_optimization_method')) + + geometry_optimization_threshold_force = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='newton', + description=''' + Value of threshold for the force modulus as convergence criterion of the + geometry_optimization_method. A geometry optimization is considered converged when + the maximum of the moduli of the force on each of the atoms is below this + threshold (possibly in combination with other criteria) + ''', + categories=[SettingsGeometryOptimization, SettingsSampling], + a_legacy=LegacyDefinition(name='geometry_optimization_threshold_force')) + + sampling_method_expansion_order = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Order up to which the potential energy surface was expanded in a Taylor series + (see sampling_method). + ''', + a_legacy=LegacyDefinition(name='sampling_method_expansion_order')) + + sampling_method = Quantity( + type=str, + shape=[], + description=''' + Type of method used to do the sampling. + + Allowed values are: + + | Sampling method | Description | + + | ------------------------------ | -------------------------------- | + + | `"geometry_optimization"` | Geometry optimization | + + | `"molecular_dynamics"` | Molecular dynamics | + + | `"montecarlo"` | (Metropolis) Monte Carlo | + + | `"steered_molecular_dynamics"` | Steered molecular dynamics (with time dependent + external forces) | + + | `"meta_dynamics"` | Biased molecular dynamics with history- + dependent Hamiltonian | + + | `"wang_landau_montecarlo"` | Monte Carlo according to the Wang-Landau + formulation. | + + | `"blue_moon"` | Blue Moon sampling | + + | `"langevin_dynamics"` | Langevin dynamics | + + | `"taylor_expansion"` | Taylor expansion of the potential energy + surface | + ''', + a_legacy=LegacyDefinition(name='sampling_method')) + + +class ScfIteration(MSection): + ''' + Every section_scf_iteration represents a self-consistent field (SCF) iteration, see + scf_info, and gives detailed information on the SCF procedure of the specified + quantities. + ''' + + m_def = Section( + aliases=['section_scf_iteration'], + validate=False, + a_legacy=LegacyDefinition(name='section_scf_iteration')) + + charge_total_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='coulomb', + description=''' + Value of the total charge, calculated with the method described in XC_method + during each self-consistent field (SCF) iteration. + ''', + a_legacy=LegacyDefinition(name='charge_total_scf_iteration')) + + electronic_kinetic_energy_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Electronic kinetic energy as defined in XC_method during the self-consistent field + (SCF) iterations. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='electronic_kinetic_energy_scf_iteration')) + + energy_change_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Stores the change of total energy with respect to the previous self-consistent + field (SCF) iteration. + ''', + categories=[ErrorEstimateContribution, EnergyValue], + a_legacy=LegacyDefinition(name='energy_change_scf_iteration')) + + energy_correction_entropy_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Entropy correction to the potential energy to compensate for the change in + occupation so that forces at finite T do not need to keep the change of occupation + in account. The array lists the values of the entropy correction for each self- + consistent field (SCF) iteration. Defined consistently with XC_method. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_correction_entropy_scf_iteration')) + + energy_correction_hartree_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Correction to the density-density electrostatic energy in the sum of eigenvalues + (that uses the mixed density on one side), and the fully consistent density- + density electrostatic energy during the self-consistent field (SCF) iterations. + Defined consistently with XC_method. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_correction_hartree_scf_iteration')) + + energy_electrostatic_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Total electrostatic energy (nuclei + electrons) during each self-consistent field + (SCF) iteration. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_electrostatic_scf_iteration')) + + energy_free_per_atom_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Free energy per atom (whose minimum gives the smeared occupation density + calculated with smearing_kind) calculated with XC_method during the self- + consistent field (SCF) iterations. + ''', + categories=[EnergyComponentPerAtom, EnergyValue], + a_legacy=LegacyDefinition(name='energy_free_per_atom_scf_iteration')) + + energy_free_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Free energy (whose minimum gives the smeared occupation density calculated with + smearing_kind) calculated with the method described in XC_method during the self- + consistent field (SCF) iterations. + ''', + categories=[EnergyComponent, EnergyValue, EnergyTotalPotential], + a_legacy=LegacyDefinition(name='energy_free_scf_iteration')) + + energy_hartree_error_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Error in the Hartree (electrostatic) potential energy during each self-consistent + field (SCF) iteration. Defined consistently with XC_method. + ''', + categories=[ErrorEstimateContribution, EnergyValue], + a_legacy=LegacyDefinition(name='energy_hartree_error_scf_iteration')) + + energy_sum_eigenvalues_per_atom_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the energy per atom, where the energy is defined as the sum of the + eigenvalues of the Hamiltonian matrix given by XC_method, during each self- + consistent field (SCF) iteration. + ''', + categories=[EnergyComponentPerAtom, EnergyValue], + a_legacy=LegacyDefinition(name='energy_sum_eigenvalues_per_atom_scf_iteration')) + + energy_sum_eigenvalues_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Sum of the eigenvalues of the Hamiltonian matrix defined by XC_method, during each + self-consistent field (SCF) iteration. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_sum_eigenvalues_scf_iteration')) + + energy_total_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total electronic energy calculated with the method described in + XC_method during each self-consistent field (SCF) iteration. + ''', + categories=[EnergyComponent, EnergyValue, EnergyTotalPotential], + a_legacy=LegacyDefinition(name='energy_total_scf_iteration')) + + energy_total_T0_per_atom_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy, calculated with the method described in XC_method per + atom extrapolated to $T=0$, based on a free-electron gas argument, during each + self-consistent field (SCF) iteration. + ''', + categories=[EnergyTotalPotentialPerAtom, EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_total_T0_per_atom_scf_iteration')) + + energy_total_T0_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy (or equivalently free energy), calculated with the + method described in XC_method and extrapolated to $T=0$, based on a free-electron + gas argument, during each self-consistent field (SCF) iteration. + ''', + categories=[EnergyComponent, EnergyValue, EnergyTotalPotential], + a_legacy=LegacyDefinition(name='energy_total_T0_scf_iteration')) + + energy_XC_potential_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value for exchange-correlation (XC) potential energy: the integral of the first + order derivative of the functional stored in XC_functional (integral of + v_xc*electron_density), i.e., the component of XC that is in the sum of the + eigenvalues. Values are given for each self-consistent field (SCF) iteration + (i.e., not the converged value, the latter being stored in energy_XC_potential). + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_XC_potential_scf_iteration')) + + energy_XC_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value for exchange-correlation (XC) energy obtained during each self-consistent + field (SCF) iteration, using the method described in XC_method. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_XC_scf_iteration')) + + spin_S2_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Stores the value of the total spin moment operator $S^2$ during the self- + consistent field (SCF) iterations of the XC_method. It can be used to calculate + the spin contamination in spin-unrestricted calculations. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='spin_S2_scf_iteration')) + + time_scf_iteration = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Total time of the self-consistent field (SCF) iteration. + ''', + categories=[TimeInfo, AccessoryInfo], + a_legacy=LegacyDefinition(name='time_scf_iteration')) + + time_scf_iteration_cpu1_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end time of a self-consistent field (SCF) iteration on CPU 1. + ''', + categories=[TimeInfo, AccessoryInfo], + a_legacy=LegacyDefinition(name='time_scf_iteration_cpu1_end')) + + time_scf_iteration_cpu1_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start time of a self-consistent field (SCF) iteration on CPU 1. + ''', + categories=[TimeInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='time_scf_iteration_cpu1_start')) + + time_scf_iteration_date_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end date of a self-consistent field (SCF) iteration as time since the + *Unix epoch* (00:00:00 UTC on 1 January 1970) in seconds. For date and times + without a timezone, the default timezone GMT is used. + ''', + categories=[TimeInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='time_scf_iteration_date_end')) + + time_scf_iteration_date_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start date of a self-consistent field (SCF) iteration as time since the + *Unix epoch* (00:00:00 UTC on 1 January 1970) in seconds. For date and times + without a timezone, the default timezone GMT is used. + ''', + categories=[TimeInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='time_scf_iteration_date_start')) + + time_scf_iteration_wall_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time at the end of a self-consistent field (SCF) + iteration. + ''', + categories=[TimeInfo, AccessoryInfo], + a_legacy=LegacyDefinition(name='time_scf_iteration_wall_end')) + + time_scf_iteration_wall_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time from the start of a self-consistent field + (SCF) iteration. + ''', + categories=[TimeInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='time_scf_iteration_wall_start')) + + energy_reference_fermi_iteration = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Fermi energy (separates occupied from unoccupied single-particle states in metals) + during the self-consistent field (SCF) iterations. + ''', + categories=[EnergyTypeReference, EnergyValue], + a_legacy=LegacyDefinition(name='energy_reference_fermi_iteration')) + + energy_reference_highest_occupied_iteration = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Highest occupied single-particle state energy (in insulators or HOMO energy in + finite systems) during the self-consistent field (SCF) iterations. + ''', + categories=[EnergyTypeReference, EnergyValue, Unused], + a_legacy=LegacyDefinition(name='energy_reference_highest_occupied_iteration')) + + energy_reference_lowest_unoccupied_iteration = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Lowest unoccupied single-particle state energy (in insulators or LUMO energy in + finite systems) during the self-consistent field (SCF) iterations. + ''', + categories=[EnergyTypeReference, EnergyValue, Unused], + a_legacy=LegacyDefinition(name='energy_reference_lowest_unoccupied_iteration')) + + +class SingleConfigurationCalculation(MSection): + ''' + Every section_single_configuration_calculation section contains the values computed + during a *single configuration calculation*, i.e. a calculation performed on a given + configuration of the system (as defined in section_system) and a given computational + method (e.g., exchange-correlation method, basis sets, as defined in section_method). + + The link between the current section_single_configuration_calculation and the related + section_system and section_method sections is established by the values stored in + single_configuration_calculation_to_system_ref and + single_configuration_to_calculation_method_ref, respectively. + + The reason why information on the system configuration and computational method is + stored separately is that several *single configuration calculations* can be performed + on the same system configuration, viz. several system configurations can be evaluated + with the same computational method. This storage strategy avoids redundancies. + ''' + + m_def = Section( + aliases=['section_single_configuration_calculation'], + validate=False, + a_legacy=LegacyDefinition(name='section_single_configuration_calculation')) + + atom_forces_free_raw = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_free, + **without** constraints. The derivatives with respect to displacements of nuclei + are evaluated in Cartesian coordinates. The (electronic) energy_free contains the + change in (fractional) occupation of the electronic eigenstates, which are + accounted for in the derivatives, yielding a truly energy-conserved quantity. + These forces may contain unitary transformations (center-of-mass translations and + rigid rotations for non-periodic systems) that are normally filtered separately + (see atom_forces_free for the filtered counterpart). Forces due to constraints + such as fixed atoms, distances, angles, dihedrals, etc. are also considered + separately (see atom_forces_free for the filtered counterpart). + ''', + categories=[AtomForcesType], + a_legacy=LegacyDefinition(name='atom_forces_free_raw')) + + atom_forces_free = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_free, + **including** constraints, if present. The derivatives with respect to + displacements of the nuclei are evaluated in Cartesian coordinates. The + (electronic) energy_free contains the information on the change in (fractional) + occupation of the electronic eigenstates, which are accounted for in the + derivatives, yielding a truly energy-conserved quantity. In addition, these forces + are obtained by filtering out the unitary transformations (center-of-mass + translations and rigid rotations for non-periodic systems, see + atom_forces_free_raw for the unfiltered counterpart). Forces due to constraints + such as fixed atoms, distances, angles, dihedrals, etc. are included (see + atom_forces_free_raw for the unfiltered counterpart). + ''', + categories=[AtomForcesType], + a_legacy=LegacyDefinition(name='atom_forces_free')) + + atom_forces_raw = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_total, + **without** constraints. The derivatives with respect to displacements of the + nuclei are evaluated in Cartesian coordinates. These forces may contain unitary + transformations (center-of-mass translations and rigid rotations for non-periodic + systems) that are normally filtered separately (see atom_forces for the filtered + counterpart). Forces due to constraints such as fixed atoms, distances, angles, + dihedrals, etc. are also considered separately (see atom_forces for the filtered + counterpart). + ''', + categories=[AtomForcesType], + a_legacy=LegacyDefinition(name='atom_forces_raw')) + + atom_forces_T0_raw = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_total_T0, + **without** constraints. The derivatives with respect to displacements of the + nuclei are evaluated in Cartesian coordinates. These forces may contain unitary + transformations (center-of-mass translations and rigid rotations for non-periodic + systems) that are normally filtered separately (see atom_forces_T0 for the + filtered counterpart). Forces due to constraints such as fixed atoms, distances, + angles, dihedrals, etc. are also considered separately (see atom_forces_T0 for the + filtered counterpart). + ''', + categories=[AtomForcesType, Unused], + a_legacy=LegacyDefinition(name='atom_forces_T0_raw')) + + atom_forces_T0 = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_total_T0, + **including** constraints, if present. The derivatives with respect to + displacements of the nuclei are evaluated in Cartesian coordinates. In addition, + these forces are obtained by filtering out the unitary transformations (center-of- + mass translations and rigid rotations for non-periodic systems, see + atom_forces_free_T0_raw for the unfiltered counterpart). Forces due to constraints + such as fixed atoms, distances, angles, dihedrals, etc. are also included (see + atom_forces_free_T0_raw for the unfiltered counterpart). + ''', + categories=[AtomForcesType, Unused], + a_legacy=LegacyDefinition(name='atom_forces_T0')) + + atom_forces = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='newton', + description=''' + Forces acting on the atoms, calculated as minus gradient of energy_total, + **including** constraints, if present. The derivatives with respect to + displacements of nuclei are evaluated in Cartesian coordinates. In addition, these + forces are obtained by filtering out the unitary transformations (center-of-mass + translations and rigid rotations for non-periodic systems, see + atom_forces_free_raw for the unfiltered counterpart). Forces due to constraints + such as fixed atoms, distances, angles, dihedrals, etc. are included (see + atom_forces_raw for the unfiltered counterpart). + ''', + categories=[AtomForcesType], + a_legacy=LegacyDefinition(name='atom_forces')) + + charge_total = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='coulomb', + description=''' + Value of the total charge, calculated with the method described in XC_method. + ''', + a_legacy=LegacyDefinition(name='charge_total')) + + electronic_kinetic_energy = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Self-consistent electronic kinetic energy as defined in XC_method. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='electronic_kinetic_energy')) + + energy_C = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Correlation (C) energy calculated with the method described in XC_functional. + ''', + categories=[EnergyComponent, EnergyValue, EnergyTypeC], + a_legacy=LegacyDefinition(name='energy_C')) + + energy_correction_entropy = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Entropy correction to the potential energy to compensate for the change in + occupation so that forces at finite T do not need to keep the change of occupation + in account. Defined consistently with XC_method. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_correction_entropy')) + + energy_correction_hartree = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Correction to the density-density electrostatic energy in the sum of eigenvalues + (that uses the mixed density on one side), and the fully consistent density- + density electrostatic energy. Defined consistently with XC_method. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_correction_hartree')) + + energy_current = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the energy calculated with calculation_method_current. energy_current is + equal to energy_total for non-perturbative methods. For perturbative methods, + energy_current is equal to the correction: energy_total minus energy_total of the + calculation_to_calculation_ref with calculation_to_calculation_kind = + starting_point (see the [method_to_method_kind wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/method- + to-method-kind)). See also [energy_current wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/energy- + current). + ''', + categories=[EnergyComponent, EnergyValue, EnergyTotalPotential], + a_legacy=LegacyDefinition(name='energy_current')) + + energy_electrostatic = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Total electrostatic energy (nuclei + electrons), defined consistently with + calculation_method. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_electrostatic')) + + energy_free_per_atom = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Free energy per atom (whose minimum gives the smeared occupation density + calculated with smearing_kind) calculated with XC_method. + ''', + categories=[EnergyComponentPerAtom, EnergyValue], + a_legacy=LegacyDefinition(name='energy_free_per_atom')) + + energy_free = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Free energy (nuclei + electrons) (whose minimum gives the smeared occupation + density calculated with smearing_kind) calculated with the method described in + XC_method. + ''', + categories=[EnergyComponent, EnergyValue, EnergyTotalPotential], + a_legacy=LegacyDefinition(name='energy_free')) + + energy_hartree_error = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Error in the Hartree (electrostatic) potential energy. Defined consistently with + XC_method. + ''', + categories=[ErrorEstimateContribution, EnergyValue], + a_legacy=LegacyDefinition(name='energy_hartree_error')) + + energy_hartree_fock_X_scaled = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Scaled exact-exchange energy that depends on the mixing parameter of the + functional. For example in hybrid functionals, the exchange energy is given as a + linear combination of exact-energy and exchange energy of an approximate DFT + functional; the exact exchange energy multiplied by the mixing coefficient of the + hybrid functional would be stored in this metadata. Defined consistently with + XC_method. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_hartree_fock_X_scaled')) + + energy_hartree_fock_X = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Converged exact-exchange (Hartree-Fock) energy. Defined consistently with + XC_method. + ''', + categories=[EnergyTypeX, EnergyComponent, EnergyValue, Unused], + a_legacy=LegacyDefinition(name='energy_hartree_fock_X')) + + energy_method_current = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the energy calculated with the method calculation_method_current. + Depending on calculation_method_kind it might be a total energy or only a + correction. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_method_current')) + + energy_sum_eigenvalues_per_atom = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the energy per atom, where the energy is defined as the sum of the + eigenvalues of the Hamiltonian matrix given by XC_method. + ''', + categories=[EnergyComponentPerAtom, EnergyValue], + a_legacy=LegacyDefinition(name='energy_sum_eigenvalues_per_atom')) + + energy_sum_eigenvalues = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Sum of the eigenvalues of the Hamiltonian matrix defined by XC_method. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_sum_eigenvalues')) + + energy_T0_per_atom = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy per atom, calculated with the method described in + XC_method and extrapolated to $T=0$, based on a free-electron gas argument. + ''', + categories=[EnergyTotalPotentialPerAtom, EnergyComponent, EnergyValue, Unused], + a_legacy=LegacyDefinition(name='energy_T0_per_atom')) + + energy_total_T0_per_atom = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy, calculated with the method described in XC_method per + atom extrapolated to $T=0$, based on a free-electron gas argument. + ''', + categories=[EnergyTotalPotentialPerAtom, EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_total_T0_per_atom')) + + energy_total_T0 = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy (or equivalently free energy), calculated with the + method described in XC_method and extrapolated to $T=0$, based on a free-electron + gas argument. + ''', + categories=[EnergyComponent, EnergyValue, EnergyTotalPotential], + a_legacy=LegacyDefinition(name='energy_total_T0')) + + energy_total = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the total energy, calculated with the method described in XC_method and + extrapolated to $T=0$, based on a free-electron gas argument. + ''', + categories=[EnergyComponent, EnergyValue, EnergyTotalPotential], + a_legacy=LegacyDefinition(name='energy_total')) + + energy_XC_functional = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the exchange-correlation (XC) energy calculated with the functional + stored in XC_functional. + ''', + categories=[EnergyTypeXC, EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_XC_functional')) + + energy_XC_potential = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the exchange-correlation (XC) potential energy: the integral of the first + order derivative of the functional stored in XC_functional (integral of + v_xc*electron_density), i.e., the component of XC that is in the sum of the + eigenvalues. Value associated with the configuration, should be the most converged + value. + ''', + categories=[EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_XC_potential')) + + energy_XC = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the exchange-correlation (XC) energy calculated with the method described + in XC_method. + ''', + categories=[EnergyTypeXC, EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_XC')) + + energy_X = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value fo the exchange (X) energy calculated with the method described in + XC_method. + ''', + categories=[EnergyTypeX, EnergyComponent, EnergyValue], + a_legacy=LegacyDefinition(name='energy_X')) + + energy_zero_point = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Value for the converged zero-point vibrations energy calculated using the method + described in zero_point_method , and used in energy_current . + ''', + a_legacy=LegacyDefinition(name='energy_zero_point')) + + hessian_matrix = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 'number_of_atoms', 3, 3], + description=''' + The matrix with the second derivative with respect to atom displacements. + ''', + a_legacy=LegacyDefinition(name='hessian_matrix')) + + lattice_vectors_reciprocal = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='1/meter', + description=''' + Reciprocal lattice vectors (in Cartesian coordinates) of the simulation cell. The + first index runs over the $x,y,z$ Cartesian coordinates, and the second index runs + over the 3 lattice vectors. + ''', + categories=[ConfigurationCore], + a_legacy=LegacyDefinition(name='lattice_vectors_reciprocal')) + + message_debug_evaluation = Quantity( + type=str, + shape=[], + description=''' + A debugging message of the computational program, associated with a *single + configuration calculation* (see section_single_configuration_calculation). + ''', + categories=[MessageDebug, Unused], + a_legacy=LegacyDefinition(name='message_debug_evaluation')) + + message_error_evaluation = Quantity( + type=str, + shape=[], + description=''' + An error message of the computational program, associated with a *single + configuration calculation* (see section_single_configuration_calculation). + ''', + categories=[MessageInfo, MessageDebug, MessageError, MessageWarning, Unused], + a_legacy=LegacyDefinition(name='message_error_evaluation')) + + message_info_evaluation = Quantity( + type=str, + shape=[], + description=''' + An information message of the computational program, associated with a *single + configuration calculation* (see section_single_configuration_calculation). + ''', + categories=[MessageInfo, MessageDebug, Unused], + a_legacy=LegacyDefinition(name='message_info_evaluation')) + + message_warning_evaluation = Quantity( + type=str, + shape=[], + description=''' + A warning message of the computational program. + ''', + categories=[MessageInfo, MessageDebug, MessageWarning, Unused], + a_legacy=LegacyDefinition(name='message_warning_evaluation')) + + number_of_scf_iterations = Quantity( + type=int, + shape=[], + description=''' + Gives the number of performed self-consistent field (SCF) iterations at a specfied + level of theory. + ''', + categories=[ScfInfo], + a_legacy=LegacyDefinition(name='number_of_scf_iterations')) + + parsing_message_debug_evaluation = Quantity( + type=str, + shape=[], + description=''' + This field is used for debugging messages of the parsing program associated with a + run, see section_run. + ''', + categories=[ParsingMessageDebug, Unused], + a_legacy=LegacyDefinition(name='parsing_message_debug_evaluation')) + + parsing_message_error_single_configuration = Quantity( + type=str, + shape=[], + description=''' + This field is used for error messages of the parsing program associated with a + single configuration calculation, see section_single_configuration_calculation. + ''', + categories=[ParsingMessageInfo, ParsingMessageError, ParsingMessageWarning, ParsingMessageDebug, Unused], + a_legacy=LegacyDefinition(name='parsing_message_error_single_configuration')) + + parsing_message_info_single_configuration = Quantity( + type=str, + shape=[], + description=''' + This field is used for info messages of the parsing program associated with a + single configuration calculation, see section_single_configuration_calculation. + ''', + categories=[ParsingMessageInfo, ParsingMessageDebug, Unused], + a_legacy=LegacyDefinition(name='parsing_message_info_single_configuration')) + + parsing_message_warning_evaluation = Quantity( + type=str, + shape=[], + description=''' + This field is used for warning messages of the parsing program associated with a + run, see section_run. + ''', + categories=[ParsingMessageInfo, ParsingMessageWarning, ParsingMessageDebug, Unused], + a_legacy=LegacyDefinition(name='parsing_message_warning_evaluation')) + + single_configuration_calculation_converged = Quantity( + type=bool, + shape=[], + description=''' + Determines whether a *single configuration calculation* in + section_single_configuration_calculation is converged. + ''', + a_legacy=LegacyDefinition(name='single_configuration_calculation_converged')) + + single_configuration_calculation_to_system_ref = Quantity( + type=Reference(SectionProxy('System')), + shape=[], + description=''' + Reference to the system (atomic configuration, cell, ...) that is calculated in + section_single_configuration_calculation. + ''', + categories=[FastAccess], + a_legacy=LegacyDefinition(name='single_configuration_calculation_to_system_ref')) + + single_configuration_to_calculation_method_ref = Quantity( + type=Reference(SectionProxy('Method')), + shape=[], + description=''' + Reference to the method used for the calculation in + section_single_configuration_calculation. + ''', + categories=[FastAccess], + a_legacy=LegacyDefinition(name='single_configuration_to_calculation_method_ref')) + + spin_S2 = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Stores the value of the total spin moment operator $S^2$ for the converged + wavefunctions calculated with the XC_method. It can be used to calculate the spin + contamination in spin-unrestricted calculations. + ''', + a_legacy=LegacyDefinition(name='spin_S2')) + + stress_tensor = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='pascal', + description=''' + Stores the final value of the default stress tensor consistent with energy_total + and calculated with the method specified in stress_tensor_method. + + This value is used (if needed) for, e.g., molecular dynamics and geometry + optimization. Alternative definitions of the stress tensor can be assigned with + stress_tensor_kind + ''', + categories=[StressTensorType], + a_legacy=LegacyDefinition(name='stress_tensor')) + + time_calculation = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the wall-clock time needed for a calculation using + calculation_method_current. Basically, it tracks the real time that has been + elapsed from start to end. + ''', + categories=[TimeInfo, AccessoryInfo], + a_legacy=LegacyDefinition(name='time_calculation')) + + time_single_configuration_calculation_cpu1_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end time of the *single configuration calculation* (see + section_single_configuration_calculation) on CPU 1. + ''', + categories=[TimeInfo, AccessoryInfo], + a_legacy=LegacyDefinition(name='time_single_configuration_calculation_cpu1_end')) + + time_single_configuration_calculation_cpu1_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start time of the *single configuration calculation* (see + section_single_configuration_calculation) on CPU 1. + ''', + categories=[TimeInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='time_single_configuration_calculation_cpu1_start')) + + time_single_configuration_calculation_date_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the end date of the *single configuration calculation* (see + section_single_configuration_calculation) as time since the *Unix epoch* (00:00:00 + UTC on 1 January 1970) in seconds. For date and times without a timezone, the + default timezone GMT is used. + ''', + categories=[TimeInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='time_single_configuration_calculation_date_end')) + + time_single_configuration_calculation_date_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the start date of the *single configuration calculation* (see + section_single_configuration_calculation) as time since the *Unix epoch* (00:00:00 + UTC on 1 January 1970) in seconds. For date and times without a timezone, the + default timezone GMT is used. + ''', + categories=[TimeInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='time_single_configuration_calculation_date_start')) + + time_single_configuration_calculation_wall_end = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time at the end of the *single configuration + calculation* (see section_single_configuration_calculation). + ''', + categories=[TimeInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='time_single_configuration_calculation_wall_end')) + + time_single_configuration_calculation_wall_start = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='second', + description=''' + Stores the internal wall-clock time from the start of the *single configuration + calculation* (see section_single_configuration_calculation). + ''', + categories=[TimeInfo, AccessoryInfo, Unused], + a_legacy=LegacyDefinition(name='time_single_configuration_calculation_wall_start')) + + zero_point_method = Quantity( + type=str, + shape=[], + description=''' + Describes the zero-point vibrations method. If skipped or an empty string is used, + it means no zero-point vibrations correction is applied. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='zero_point_method')) + + enthalpy = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Value of the calculated enthalpy i.e. energy_total + pressure * volume. + ''', + categories=[EnergyComponent, EnergyValue, Unused], + a_legacy=LegacyDefinition(name='energy_enthalpy')) + + pressure = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='pascal', + description=''' + Value of the pressure of the system. + ''', + a_legacy=LegacyDefinition(name='pressure')) + + temperature = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='kelvin', + description=''' + Value of the temperature of the system. + ''', + a_legacy=LegacyDefinition(name='temperature')) + + time_step = Quantity( + type=int, + shape=[], + description=''' + The number of time steps with respect to the start of the calculation. + ''', + a_legacy=LegacyDefinition(name='time_step')) + + energy_C_mGGA = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Component of the correlation (C) energy at the GGA (or MetaGGA) level using the + self-consistent density of the target XC functional (full unscaled value, i.e., + not scaled due to exact-exchange mixing). + ''', + categories=[EnergyComponent, EnergyValue, EnergyTypeC, Unused], + a_legacy=LegacyDefinition(name='energy_C_mGGA')) + + energy_reference_fermi = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Fermi energy (separates occupied from unoccupied single-particle states in metals) + ''', + categories=[EnergyTypeReference, EnergyValue], + a_legacy=LegacyDefinition(name='energy_reference_fermi')) + + energy_reference_highest_occupied = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Highest occupied single-particle state energy (in insulators or HOMO energy in + finite systems) + ''', + categories=[EnergyTypeReference, EnergyValue], + a_legacy=LegacyDefinition(name='energy_reference_highest_occupied')) + + energy_reference_lowest_unoccupied = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Lowest unoccupied single-particle state energy (in insulators or LUMO energy in + finite systems) + ''', + categories=[EnergyTypeReference, EnergyValue], + a_legacy=LegacyDefinition(name='energy_reference_lowest_unoccupied')) + + energy_X_mGGA_scaled = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Component of the exchange (X) energy at the GGA (or MetaGGA) level, using the self + consistent density of the target functional, scaled accordingly to the mixing + parameter. + ''', + categories=[EnergyComponent, EnergyValue, Unused], + a_legacy=LegacyDefinition(name='energy_X_mGGA_scaled')) + + energy_X_mGGA = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Component of the exchange (X) energy at the GGA (or MetaGGA) level using the self + consistent density of the target functional (full unscaled value, i.e., not scaled + due to exact-exchange mixing). + ''', + categories=[EnergyTypeX, EnergyComponent, EnergyValue, Unused], + a_legacy=LegacyDefinition(name='energy_X_mGGA')) + + gw_fermi_energy = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + GW Fermi energy + ''', + a_legacy=LegacyDefinition(name='gw_fermi_energy')) + + gw_fundamental_gap = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + GW fundamental band gap + ''', + a_legacy=LegacyDefinition(name='gw_fundamental_gap')) + + gw_optical_gap = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + GW optical band gap + ''', + a_legacy=LegacyDefinition(name='gw_optical_gap')) + + gw_self_energy_c = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Diagonal matrix elements of the correlation self-energy + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_c')) + + gw_self_energy_x = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Diagonal matrix elements of the exchange self-energy + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_x')) + + gw_xc_potential = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Diagonal matrix elements of the exchange-correlation potential + ''', + a_legacy=LegacyDefinition(name='gw_xc_potential')) + + section_atom_projected_dos = SubSection( + sub_section=SectionProxy('AtomProjectedDos'), + repeats=True, + a_legacy=LegacyDefinition(name='section_atom_projected_dos')) + + section_atomic_multipoles = SubSection( + sub_section=SectionProxy('AtomicMultipoles'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_atomic_multipoles')) + + section_basis_set = SubSection( + sub_section=SectionProxy('BasisSet'), + repeats=True, + a_legacy=LegacyDefinition(name='section_basis_set')) + + section_calculation_to_calculation_refs = SubSection( + sub_section=SectionProxy('CalculationToCalculationRefs'), + repeats=True, + a_legacy=LegacyDefinition(name='section_calculation_to_calculation_refs')) + + section_calculation_to_folder_refs = SubSection( + sub_section=SectionProxy('CalculationToFolderRefs'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_calculation_to_folder_refs')) + + section_dos = SubSection( + sub_section=SectionProxy('Dos'), + repeats=True, + a_legacy=LegacyDefinition(name='section_dos')) + + section_eigenvalues = SubSection( + sub_section=SectionProxy('Eigenvalues'), + repeats=True, + a_legacy=LegacyDefinition(name='section_eigenvalues')) + + section_energy_code_independent = SubSection( + sub_section=SectionProxy('EnergyCodeIndependent'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_energy_code_independent')) + + section_energy_van_der_Waals = SubSection( + sub_section=SectionProxy('EnergyVanDerWaals'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_energy_van_der_Waals')) + + section_energy_contribution = SubSection( + sub_section=SectionProxy('EnergyContribution'), + repeats=True, + a_legacy=LegacyDefinition(name='section_energy_contribution')) + + section_k_band_normalized = SubSection( + sub_section=SectionProxy('KBandNormalized'), + repeats=True, + a_legacy=LegacyDefinition(name='section_k_band_normalized')) + + section_k_band = SubSection( + sub_section=SectionProxy('KBand'), + repeats=True, + a_legacy=LegacyDefinition(name='section_k_band')) + + section_scf_iteration = SubSection( + sub_section=SectionProxy('ScfIteration'), + repeats=True, + a_legacy=LegacyDefinition(name='section_scf_iteration')) + + section_species_projected_dos = SubSection( + sub_section=SectionProxy('SpeciesProjectedDos'), + repeats=True, + a_legacy=LegacyDefinition(name='section_species_projected_dos')) + + section_stress_tensor = SubSection( + sub_section=SectionProxy('StressTensor'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_stress_tensor')) + + section_volumetric_data = SubSection( + sub_section=SectionProxy('VolumetricData'), + repeats=True, + a_legacy=LegacyDefinition(name='section_volumetric_data')) + + section_excited_states = SubSection( + sub_section=SectionProxy('ExcitedStates'), + repeats=True, + a_legacy=LegacyDefinition(name='section_excited_states')) + + +class SpeciesProjectedDos(MSection): + ''' + Section collecting the information on a species-projected density of states (DOS) + evaluation. + ''' + + m_def = Section( + aliases=['section_species_projected_dos'], + validate=False, + a_legacy=LegacyDefinition(name='section_species_projected_dos')) + + number_of_lm_species_projected_dos = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $l$, $m$ combinations for the species-projected density of + states (DOS) defined in section_species_projected_dos. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_lm_species_projected_dos')) + + number_of_species_projected_dos_values = Quantity( + type=int, + shape=[], + description=''' + Gives the number of energy values for the species-projected density of states + (DOS) defined in section_species_projected_dos. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_species_projected_dos_values')) + + number_of_species = Quantity( + type=int, + shape=[], + description=''' + Gives the number of species for the species-projected density of states (DOS) + defined in section_species_projected_dos. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_species')) + + species_projected_dos_energies_normalized = Quantity( + type=np.dtype(np.float64), + shape=['number_of_species_projected_dos_values'], + unit='joule', + description=''' + Contains the set of discrete energy values with respect to the top of the valence + band for the species-projected density of states (DOS). It is derived from the + species_projected_dos_energies species field. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='species_projected_dos_energies_normalized')) + + species_projected_dos_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_species_projected_dos_values'], + unit='joule', + description=''' + Contains the set of discrete energy values for the species-projected density of + states (DOS). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='species_projected_dos_energies')) + + species_projected_dos_lm = Quantity( + type=np.dtype(np.int32), + shape=['number_of_lm_species_projected_dos', 2], + description=''' + Consists of tuples of $l$ and $m$ values for all given values in the + species_projected_dos_values_lm species field. + + The quantum number $l$ represents the azimuthal quantum number, whereas for the + quantum number $m$, besides the conventional use as magnetic quantum number ($l+1$ + integer values from $-l$ to $l$), a set of different conventions is accepted. The + adopted convention is specified by atom_projected_dos_m_kind. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='species_projected_dos_lm')) + + species_projected_dos_m_kind = Quantity( + type=str, + shape=[], + description=''' + Specifies the kind of the integer numbers $m$ used in species_projected_dos_lm. + + Allowed values are listed in the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind) + and can be (quantum) numbers of + + * spherical + + * polynomial + + * real_orbital + + * integrated + + functions or values. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='species_projected_dos_m_kind')) + + species_projected_dos_species_label = Quantity( + type=str, + shape=['number_of_species'], + description=''' + Contains labels of the atomic species for the species-projected density of states + (DOS). + + Differently from atom_labels, which allow more than one label for the same atomic + species (by adding a number or a string to the label), this list is expected to + refer to actual atomic species, i.e. belonging to the periodic table of elements. + Thus, the species-projected DOS are expected to be as many as the different atomic + species in the system. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='species_projected_dos_species_label')) + + species_projected_dos_values_lm = Quantity( + type=np.dtype(np.float64), + shape=['number_of_lm_species_projected_dos', 'number_of_spin_channels', 'number_of_species', 'number_of_species_projected_dos_values'], + description=''' + Holds species-projected density of states (DOS) values, divided into contributions + from each $l,m$ channel. + + Here, there are as many species-projected DOS as the number of species, + number_of_species. The list of labels of the species is given in + species_projected_dos_species_label. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='species_projected_dos_values_lm')) + + species_projected_dos_values_total = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_species', 'number_of_species_projected_dos_values'], + description=''' + Holds species-projected density of states (DOS) values, summed up over all + azimuthal quantum numbers $l$. + + Here, there are as many species-projected DOS as the number of species, + number_of_species. The list of labels of the species is given in + species_projected_dos_species_label. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='species_projected_dos_values_total')) + + +class SpringerMaterial(MSection): + ''' + Every section_springer_material contains results of classification of materials with + the same formula according to Springer Materials - it contains + section_springer_classsification, section_springer_compound, section_springer_id, + section_springer_references + ''' + + m_def = Section( + aliases=['section_springer_material'], + validate=False, + a_legacy=LegacyDefinition(name='section_springer_material')) + + springer_id = Quantity( + type=str, + shape=[], + description=''' + Id of the classified material according to Springer Materials + ''', + a_legacy=LegacyDefinition(name='springer_id')) + + springer_alphabetical_formula = Quantity( + type=str, + shape=[], + description=''' + The alphabetical formula of the material according to Springer Materials Database + ''', + a_legacy=LegacyDefinition(name='springer_alphabetical_formula')) + + springer_url = Quantity( + type=str, + shape=[], + description=''' + Url to the source page in Springer Materials describing the current entry + ''', + a_legacy=LegacyDefinition(name='springer_url')) + + springer_compound_class = Quantity( + type=str, + shape=['N'], + description=''' + Name of a class of the current compound, as defined in by Springer Materials. This + is a property of the chemical formula of the compound + ''', + a_legacy=LegacyDefinition(name='springer_compound_class')) + + springer_classification = Quantity( + type=str, + shape=['N'], + description=''' + Contains the classification name of the current material according to Springer + Materials + ''', + a_legacy=LegacyDefinition(name='springer_classification')) + + section_springer_id = SubSection( + sub_section=SectionProxy('SpringerId'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_springer_id')) + + +class SpringerId(MSection): + ''' + Identifiers used by Springer Materials + ''' + + m_def = Section( + aliases=['section_springer_id'], + validate=False, + a_legacy=LegacyDefinition(name='section_springer_id')) + + +class StdSystem(MSection): + ''' + Section containing symmetry information that is specific to the standardized system. + The standardized system is defined as given by spglib and the details can be found + from https://arxiv.org/abs/1506.01455 + ''' + + m_def = Section( + aliases=['section_std_system'], + validate=False, + a_legacy=LegacyDefinition(name='section_std_system')) + + atom_positions_std = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms_std', 3], + description=''' + Standardized atom positions in reduced units. + ''', + a_legacy=LegacyDefinition(name='atom_positions_std')) + + atomic_numbers_std = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms_std'], + description=''' + Atomic numbers of the atoms in the standardized cell. + ''', + a_legacy=LegacyDefinition(name='atomic_numbers_std')) + + equivalent_atoms_std = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms_std'], + description=''' + Gives a mapping table of atoms to symmetrically independent atoms in the + standardized cell. This is used to find symmetrically equivalent atoms. + ''', + a_legacy=LegacyDefinition(name='equivalent_atoms_std')) + + lattice_vectors_std = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='meter', + description=''' + Standardized lattice vectors of the conventional cell. The vectors are the rows of + this matrix. + ''', + a_legacy=LegacyDefinition(name='lattice_vectors_std')) + + number_of_atoms_std = Quantity( + type=int, + shape=[], + description=''' + Number of atoms in standardized system. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_atoms_std')) + + wyckoff_letters_std = Quantity( + type=str, + shape=['number_of_atoms_std'], + description=''' + Wyckoff letters for atoms in the standardized cell. + ''', + a_legacy=LegacyDefinition(name='wyckoff_letters_std')) + + +class StressTensor(MSection): + ''' + Section collecting alternative values to stress_tensor that have been calculated. This + section allows the storage of multiple definitions and evaluated values of the stress + tensor, while only one definition is used for, e.g., molecular dynamics or geometry + optimization (if needed). + ''' + + m_def = Section( + aliases=['section_stress_tensor'], + validate=False, + a_legacy=LegacyDefinition(name='section_stress_tensor')) + + stress_tensor_kind = Quantity( + type=str, + shape=[], + description=''' + Specifies the method used to compute the stress tensor stored in + stress_tensor_value. This is an *alternative* to the stress tensor defined in + stress_tensor_method, which is stored in stress_tensor. + + This field allows for multiple definitions and evaluated values of the stress + tensor, while only one definition is used for, e.g., molecular dynamics and + geometry optimization. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='stress_tensor_kind')) + + stress_tensor_value = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='pascal', + description=''' + Contains the value of the stress tensor of the kind defined in stress_tensor_kind. + This is an *alternative* to the stress tensor defined in stress_tensor_method. + + This field allows for multiple definitions and evaluated values of the stress + tensor, while only one definition is used for, e.g., molecular dynamics and + geometry optimization. + ''', + categories=[StressTensorType, Unused], + a_legacy=LegacyDefinition(name='stress_tensor_value')) + + +class Symmetry(MSection): + ''' + Section containing information about the symmetry properties of the system. + ''' + + m_def = Section( + aliases=['section_symmetry'], + validate=False, + a_legacy=LegacyDefinition(name='section_symmetry')) + + bravais_lattice = Quantity( + type=str, + shape=[], + description=''' + Identifier for the Bravais lattice in Pearson notation. The first lowercase letter + identifies the crystal family and can be one of the following: a (triclinic), b + (monoclinic), o (orthorhombic), t (tetragonal), h (hexagonal) or c (cubic). The + second uppercase letter identifies the centring and can be one of the following: P + (primitive), S (face centred), I (body centred), R (rhombohedral centring) or F + (all faces centred). + ''', + a_legacy=LegacyDefinition(name='bravais_lattice')) + + choice = Quantity( + type=str, + shape=[], + description=''' + String that specifies the centering, origin and basis vector settings of the 3D + space group that defines the symmetry group of the simulated physical system (see + section_system). Values are as defined by spglib. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='choice')) + + crystal_system = Quantity( + type=str, + shape=[], + description=''' + Name of the crystal system. Can be one of the following: triclinic, monoclinic, + orthorhombic, tetragonal, trigonal, hexagonal or cubic. + ''', + a_legacy=LegacyDefinition(name='crystal_system')) + + hall_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + The Hall number for this system. + ''', + a_legacy=LegacyDefinition(name='hall_number')) + + hall_symbol = Quantity( + type=str, + shape=[], + description=''' + The Hall symbol for this system. + ''', + a_legacy=LegacyDefinition(name='hall_symbol')) + + international_short_symbol = Quantity( + type=str, + shape=[], + description=''' + Specifies the International Union of Crystallography (IUC) short symbol of the 3D + space group of this system + ''', + a_legacy=LegacyDefinition(name='international_short_symbol')) + + origin_shift = Quantity( + type=np.dtype(np.float64), + shape=[3], + description=''' + Vector $\\mathbf{p}$ from the origin of the standardized system to the origin of + the original system. Together with the matrix $\\mathbf{P}$, found in + space_group_3D_transformation_matrix, the transformation between the standardized + coordinates $\\mathbf{x}_s$ and original coordinates $\\mathbf{x}$ is then given by + $\\mathbf{x}_s = \\mathbf{P} \\mathbf{x} + \\mathbf{p}$. + ''', + a_legacy=LegacyDefinition(name='origin_shift')) + + point_group = Quantity( + type=str, + shape=[], + description=''' + Symbol of the crystallographic point group in the Hermann-Mauguin notation. + ''', + a_legacy=LegacyDefinition(name='point_group')) + + space_group_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Specifies the International Union of Crystallography (IUC) number of the 3D space + group of this system. + ''', + a_legacy=LegacyDefinition(name='space_group_number')) + + symmetry_method = Quantity( + type=str, + shape=[], + description=''' + Identifies the source of the symmetry information contained within this section. + If equal to 'spg_normalized' the information comes from a normalization step. + ''', + a_legacy=LegacyDefinition(name='symmetry_method')) + + transformation_matrix = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + description=''' + Matrix $\\mathbf{P}$ that is used to transform the standardized coordinates to the + original coordinates. Together with the vector $\\mathbf{p}$, found in + space_group_3D_origin_shift, the transformation between the standardized + coordinates $\\mathbf{x}_s$ and original coordinates $\\mathbf{x}$ is then given by + $\\mathbf{x}_s = \\mathbf{P} \\mathbf{x} + \\mathbf{p}$. + ''', + a_legacy=LegacyDefinition(name='transformation_matrix')) + + section_original_system = SubSection( + sub_section=SectionProxy('OriginalSystem'), + repeats=True, + a_legacy=LegacyDefinition(name='section_original_system')) + + section_primitive_system = SubSection( + sub_section=SectionProxy('PrimitiveSystem'), + repeats=True, + a_legacy=LegacyDefinition(name='section_primitive_system')) + + section_std_system = SubSection( + sub_section=SectionProxy('StdSystem'), + repeats=True, + a_legacy=LegacyDefinition(name='section_std_system')) + + +class SystemToSystemRefs(MSection): + ''' + Section that describes the relationship between different section_system sections. For + instance, if a phonon calculation using a finite difference approach is performed the + force evaluation is typically done in a larger supercell but the properties such as + the phonon band structure are still calculated for the primitive cell. + + The kind of relationship between the system defined in this section and the referenced + one is described by system_to_system_kind. The referenced section_system is identified + via system_to_system_ref. + ''' + + m_def = Section( + aliases=['section_system_to_system_refs'], + validate=False, + a_legacy=LegacyDefinition(name='section_system_to_system_refs')) + + system_to_system_kind = Quantity( + type=str, + shape=[], + description=''' + String defining the relationship between the referenced section_system and the + present section_system. Often systems are connected for example if a phonon + calculation using finite differences is performed the force ealuation is done in a + larger supercell but properties such as the phonon band structure are still + calculated for the primitive cell. Hence, the need of keeping track of these + connected systems. The referenced system is identified via system_to_system_ref. + ''', + a_legacy=LegacyDefinition(name='system_to_system_kind')) + + system_to_system_ref = Quantity( + type=Reference(SectionProxy('System')), + shape=[], + description=''' + Reference to another system. The kind of relationship between the present and the + referenced section_system is specified by system_to_system_kind. + ''', + a_legacy=LegacyDefinition(name='system_to_system_ref')) + + +class System(MSection): + ''' + Every section_system contains all needed properties required to describe the simulated + physical system, e.g. the given atomic configuration, the definition of periodic cell + (if present), the external potentials and other parameters. + ''' + + m_def = Section( + aliases=['section_system'], + validate=False, + a_legacy=LegacyDefinition(name='section_system')) + + atom_atom_number = Quantity( + type=np.dtype(np.int32), + shape=['number_of_sites'], + description=''' + Atomic number Z of the atom. + ''', + a_legacy=LegacyDefinition(name='atom_atom_number')) + + atom_concentrations = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms'], + description=''' + concentration of the atom species in a variable composition, by default it should + be considered an array of ones. Summing these should give the number_of_sites + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='atom_concentrations')) + + atom_labels = Quantity( + type=str, + shape=['number_of_atoms'], + description=''' + Labels of the atoms. These strings identify the atom kind and conventionally start + with the symbol of the atomic species, possibly followed by the atomic number. The + same atomic species can be labeled with more than one atom_labels in order to + distinguish, e.g., atoms of the same species assigned to different atom-centered + basis sets or pseudo-potentials, or simply atoms in different locations in the + structure (e.g., bulk and surface). These labels can also be used for *particles* + that do not correspond to physical atoms (e.g., ghost atoms in some codes using + atom-centered basis sets). This metadata defines a configuration and is therefore + required. + ''', + categories=[ConfigurationCore], + a_legacy=LegacyDefinition(name='atom_labels')) + + atom_positions = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='meter', + description=''' + Positions of all the atoms, in Cartesian coordinates. This metadata defines a + configuration and is therefore required. For alloys where concentrations of + species are given for each site in the unit cell, it stores the position of the + sites. + ''', + categories=[ConfigurationCore], + a_legacy=LegacyDefinition(name='atom_positions')) + + atom_species = Quantity( + type=np.dtype(np.int32), + shape=['number_of_atoms'], + description=''' + Species of the atom (normally the atomic number Z, 0 or negative for unidentifed + species or particles that are not atoms. + ''', + a_legacy=LegacyDefinition(name='atom_species')) + + atom_velocities = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3], + unit='meter / second', + description=''' + Velocities of the nuclei, defined as the change in Cartesian coordinates of the + nuclei with respect to time. + ''', + a_legacy=LegacyDefinition(name='atom_velocities')) + + configuration_periodic_dimensions = Quantity( + type=bool, + shape=[3], + description=''' + Array labeling which of the lattice vectors use periodic boundary conditions. Note + for the parser developers: This value is not expected to be given for each + section_single_configuration_calculation. It is assumed to be valid from the + section_single_configuration_calculation where it is defined for all subsequent + section_single_configuration_calculation in section_run, until redefined. + ''', + categories=[ConfigurationCore], + a_legacy=LegacyDefinition(name='configuration_periodic_dimensions')) + + configuration_raw_gid = Quantity( + type=str, + shape=[], + description=''' + checksum of the configuration_core, i.e. the geometry of the system. The values + are not normalized in any way so equivalent configurations might have different + values + ''', + a_legacy=LegacyDefinition(name='configuration_raw_gid')) + + embedded_system = Quantity( + type=bool, + shape=[], + description=''' + Is the system embedded into a host geometry?. + ''', + categories=[ConfigurationCore, Unused], + a_legacy=LegacyDefinition(name='embedded_system')) + + lattice_vectors = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='meter', + description=''' + Holds the lattice vectors (in Cartesian coordinates) of the simulation cell. The + last (fastest) index runs over the $x,y,z$ Cartesian coordinates, and the first + index runs over the 3 lattice vectors. + ''', + categories=[ConfigurationCore], + a_legacy=LegacyDefinition(name='lattice_vectors')) + + local_rotations = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms', 3, 3], + description=''' + A rotation matrix defining the orientation of each atom. If the rotation matrix + only needs to be specified for some atoms, the remaining atoms should set it to + the zero matrix (not the identity!) + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='local_rotations')) + + number_of_atoms = Quantity( + type=int, + shape=[], + description=''' + Stores the total number of atoms used in the calculation. For alloys where + concentrations of species are given for each site in the unit cell, it stores the + number of sites. + ''', + a_legacy=LegacyDefinition(name='number_of_atoms')) + + number_of_sites = Quantity( + type=int, + shape=[], + description=''' + number of sites in a variable composition representation. By default (no variable + composition) it is the same as number_of_atoms. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_sites')) + + SC_matrix = Quantity( + type=np.dtype(np.int32), + shape=[3, 3], + description=''' + Specifies the matrix that transforms the unit-cell into the super-cell in which + the actual calculation is performed. + ''', + a_legacy=LegacyDefinition(name='SC_matrix')) + + simulation_cell = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='meter', + description=''' + DEPRECATED, use lattice_vectors instead. Holds the lattice vectors (in Cartesian + coordinates) of the simulation cell. The last (fastest) index runs over the + $x,y,z$ Cartesian coordinates, and the first index runs over the 3 lattice + vectors. + ''', + categories=[ConfigurationCore], + a_legacy=LegacyDefinition(name='simulation_cell')) + + symmorphic = Quantity( + type=bool, + shape=[], + description=''' + Is the space group symmorphic? Set to True if all translations are zero. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='symmorphic')) + + system_composition = Quantity( + type=str, + shape=[], + description=''' + Composition, i.e. cumulative chemical formula with atoms ordered by decreasing + atomic number Z. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='system_composition')) + + system_configuration_consistent = Quantity( + type=bool, + shape=[], + description=''' + Flag set is the configuration is consistent + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='system_configuration_consistent')) + + system_name = Quantity( + type=str, + shape=[], + description=''' + Specifies the name of the system. This information is provided by the user in some + codes and is stored here for debugging or visualization purposes. + ''', + a_legacy=LegacyDefinition(name='system_name')) + + system_reweighted_composition = Quantity( + type=str, + shape=[], + description=''' + Composition, i.e. cumulative chemical with atoms ordered by decreasing atomic + number Z reweighted so that the sum is close to 100, and values are rounded up, + and are stable (i.e. it is a fixed point). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='system_reweighted_composition')) + + system_type = Quantity( + type=str, + shape=[], + description=''' + Type of the system + ''', + a_legacy=LegacyDefinition(name='system_type')) + + time_reversal_symmetry = Quantity( + type=bool, + shape=[], + description=''' + Is time-reversal symmetry present? + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='time_reversal_symmetry')) + + chemical_composition = Quantity( + type=str, + shape=[], + description=''' + The chemical composition as full formula of the system, based on atom species. + ''', + a_legacy=LegacyDefinition(name='chemical_composition')) + + chemical_composition_reduced = Quantity( + type=str, + shape=[], + description=''' + The chemical composition as reduced formula of the system, based on atom species. + ''', + a_legacy=LegacyDefinition(name='chemical_composition_reduced')) + + chemical_composition_bulk_reduced = Quantity( + type=str, + shape=[], + description=''' + The chemical composition as reduced bulk formula of the system, based on atom + species. + ''', + a_legacy=LegacyDefinition(name='chemical_composition_bulk_reduced')) + + number_of_electrons = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + description=''' + Number of electrons in system + ''', + categories=[ConfigurationCore], + a_legacy=LegacyDefinition(name='number_of_electrons')) + + topology_ref = Quantity( + type=Reference(SectionProxy('Topology')), + shape=[], + description=''' + Reference to the topology used for this system; if not given, the trivial topology + should be assumed. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='topology_ref')) + + is_representative = Quantity( + type=bool, + shape=[], + description=''' + Most systems in a run are only minor variations of each other. Systems marked + representative where chosen to be representative for all systems in the run. + ''', + a_legacy=LegacyDefinition(name='is_representative')) + + section_prototype = SubSection( + sub_section=SectionProxy('Prototype'), + repeats=True, + categories=[FastAccess], + a_legacy=LegacyDefinition(name='section_prototype')) + + section_springer_material = SubSection( + sub_section=SectionProxy('SpringerMaterial'), + repeats=True, + categories=[FastAccess], + a_legacy=LegacyDefinition(name='section_springer_material')) + + section_symmetry = SubSection( + sub_section=SectionProxy('Symmetry'), + repeats=True, + categories=[FastAccess], + a_legacy=LegacyDefinition(name='section_symmetry')) + + section_system_to_system_refs = SubSection( + sub_section=SectionProxy('SystemToSystemRefs'), + repeats=True, + a_legacy=LegacyDefinition(name='section_system_to_system_refs')) + + section_soap = SubSection( + sub_section=SectionProxy('Soap'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_soap')) + + +class ThermodynamicalProperties(MSection): + ''' + Section that defines thermodynamical properties about the system in a + section_frame_sequence. + ''' + + m_def = Section( + aliases=['section_thermodynamical_properties'], + validate=False, + a_legacy=LegacyDefinition(name='section_thermodynamical_properties')) + + helmholz_free_energy = Quantity( + type=np.dtype(np.float64), + shape=['number_of_thermodynamical_property_values'], + unit='joule', + description=''' + Stores the Helmholtz free energy per unit cell at constant volume of a + thermodynamic calculation. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='helmholz_free_energy')) + + number_of_thermodynamical_property_values = Quantity( + type=int, + shape=[], + description=''' + Gives the number of thermal properties values available in + section_thermodynamical_properties. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_thermodynamical_property_values')) + + thermodynamical_properties_calculation_method = Quantity( + type=str, + shape=[], + description=''' + Method used to calculate the thermodynamic quantities. + + Valid values: + + * harmonic + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='thermodynamical_properties_calculation_method')) + + thermodynamical_property_heat_capacity_C_v = Quantity( + type=np.dtype(np.float64), + shape=['number_of_thermodynamical_property_values'], + unit='joule / kelvin', + description=''' + Stores the heat capacity per cell unit at constant volume. + ''', + a_legacy=LegacyDefinition(name='thermodynamical_property_heat_capacity_C_v')) + + @derived( + type=np.dtype(np.float64), + shape=['number_of_thermodynamical_property_values'], + unit='joule / kelvin * kilogram', + description=''' + Stores the specific heat capacity at constant volume. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='specific_heat_capacity'), + cached=True + ) + def specific_heat_capacity(self) -> np.array: + """Returns the specific heat capacity by dividing the heat capacity per + cell with the mass of the atoms in the cell. + """ + import nomad.atomutils + s_frame_sequence = self.m_parent + first_frame = s_frame_sequence.frame_sequence_local_frames_ref[0] + system = first_frame.single_configuration_calculation_to_system_ref + atomic_numbers = system.atom_species + mass_per_unit_cell = nomad.atomutils.get_summed_atomic_mass(atomic_numbers) + heat_capacity = self.thermodynamical_property_heat_capacity_C_v + specific_heat_capacity = heat_capacity / mass_per_unit_cell + + return specific_heat_capacity + + thermodynamical_property_temperature = Quantity( + type=np.dtype(np.float64), + shape=['number_of_thermodynamical_property_values'], + unit='kelvin', + description=''' + Specifies the temperatures at which properties such as the Helmholtz free energy + are calculated. + ''', + a_legacy=LegacyDefinition(name='thermodynamical_property_temperature')) + + vibrational_free_energy_at_constant_volume = Quantity( + type=np.dtype(np.float64), + shape=['number_of_thermodynamical_property_values'], + unit='joule', + description=''' + Holds the vibrational free energy per atom at constant volume. + ''', + a_legacy=LegacyDefinition(name='vibrational_free_energy_at_constant_volume')) + + specific_vibrational_free_energy_at_constant_volume = Quantity( + type=np.dtype(np.float64), + shape=['number_of_thermodynamical_property_values'], + unit='joule / kilogram', + description=''' + Stores the specific vibrational free energy at constant volume. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='specific_vibrational_free_energy_at_constant_volume')) + + +class VolumetricData(MSection): + ''' + Section defining a set of volumetric data on a uniform real-space grid. + + To store an array (e.g. a density or a potential), define: + + * three grid point displacement vectors ("displacements") + + * number of grid points along each axis ("nx", "ny" and "nz") + + * the origin of the coordinate system, i.e. coordinates of the first grid + + point ("origin") + + * how many spatial functions are represented, e.g., two for a + + normal spin-polarized density ("multiplicity") + + * the values for each grid point ("values") + + * the unit that applies to each value ("units") + + * the kind of array represented by the volumetric data ("kind"). + + Allowed kinds are (please add new kinds as necessary): "density", + + "potential_hartree" and "potential_effective". Densities and + + potentials that are spin-polarized should have multiplicity two. + + Rules for more complex spins are to be decided when necessary. + ''' + + m_def = Section( + aliases=['section_volumetric_data'], + validate=False, + a_legacy=LegacyDefinition(name='section_volumetric_data')) + + volumetric_data_displacements = Quantity( + type=np.dtype(np.float64), + shape=[3, 3], + unit='meter', + description=''' + displacement vectors between grid points along each axis; same indexing rules as + lattice_vectors. In many cases, displacements and number of points are related to + lattice_vectors through: [displacement] * [number of points + N] = + [lattice_vector],where N is 1 for periodic directions and 0 for non-periodic ones + ''', + a_legacy=LegacyDefinition(name='volumetric_data_displacements')) + + volumetric_data_kind = Quantity( + type=str, + shape=[], + description=''' + The kind of function, e.g. density, potential_hartree, potential_effective. The + unit of measurement for "volumetric_data_values" depends on the kind: Densities + are 1/m^3 and potentials are J/m^3. See [full specification on the + wiki](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/volumetric-data). + ''', + a_legacy=LegacyDefinition(name='volumetric_data_kind')) + + volumetric_data_multiplicity = Quantity( + type=int, + shape=[], + description=''' + number of functions stored + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='volumetric_data_multiplicity')) + + volumetric_data_nx = Quantity( + type=int, + shape=[], + description=''' + number of points along x axis + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='volumetric_data_nx')) + + volumetric_data_ny = Quantity( + type=int, + shape=[], + description=''' + number of points along y axis + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='volumetric_data_ny')) + + volumetric_data_nz = Quantity( + type=int, + shape=[], + description=''' + number of points along z axis + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='volumetric_data_nz')) + + volumetric_data_origin = Quantity( + type=np.dtype(np.float64), + shape=[3], + description=''' + location of the first grid point; same coordinate system as atom_positions when + applicable. + ''', + a_legacy=LegacyDefinition(name='volumetric_data_origin')) + + volumetric_data_values = Quantity( + type=np.dtype(np.float64), + shape=['volumetric_data_multiplicity', 'volumetric_data_nx', 'volumetric_data_ny', 'volumetric_data_nz'], + description=''' + Array of shape (multiplicity, nx, ny, nz) containing the values. The units of + these values depend on which kind of data the values represent; see + "volumetric_data_kind". + ''', + a_legacy=LegacyDefinition(name='volumetric_data_values')) + + +class XCFunctionals(MSection): + ''' + Section containing one of the exchange-correlation (XC) functionals for the present + section_method that are combined to form the XC_functional. + ''' + + m_def = Section( + aliases=['section_XC_functionals'], + validate=False, + a_legacy=LegacyDefinition(name='section_XC_functionals')) + + XC_functional_name = Quantity( + type=str, + shape=[], + description=''' + Provides the name of one of the exchange and/or correlation (XC) functionals + combined in XC_functional. + + The valid unique names that can be used are listed in the [XC_functional wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- + functional). + + *NOTE*: This value should refer to a correlation, an exchange or an exchange- + correlation functional only. + ''', + categories=[SettingsPhysicalParameter], + a_legacy=LegacyDefinition(name='XC_functional_name')) + + XC_functional_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Contains an associative list of non-default values of the parameters for the + functional declared in XC_functional_name of the section_XC_functionals section. + + For example, if a calculations using a hybrid XC functional (e.g., HSE06) + specifies a user-given value of the mixing parameter between exact and GGA + exchange, then this non-default value is stored in this metadata. + + The labels and units of these values are defined in the paragraph dedicated to the + specified functional declared in XC_functional_name of the [XC_functional wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- + functional). + + If this metadata is not given, the default parameter values for the + XC_functional_name are assumed. + ''', + categories=[SettingsPhysicalParameter], + a_legacy=LegacyDefinition(name='XC_functional_parameters')) + + XC_functional_weight = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Provides the value of the weight for the exchange, correlation, or exchange- + correlation functional declared in XC_functional_name (see + section_XC_functionals). + + This weight is used in the linear combination of the different XC functional names + (XC_functional_name) in different section_XC_functionals sections to form the + XC_functional used for evaluating energy_XC_functional and related quantities. + + If not specified then the default is set to 1. + ''', + categories=[SettingsPhysicalParameter], + a_legacy=LegacyDefinition(name='XC_functional_weight')) + + +class GeometryOptimization(MSection): + ''' + Section containing the results of a geometry_optimization workflow. + ''' + + m_def = Section( + validate=False, + a_legacy=LegacyDefinition(name='section_geometry_optimization')) + + geometry_optimization_type = Quantity( + type=str, + shape=[], + description=''' + The type of geometry optimization can either be ionic, cell_shape, cell_volume. + ''', + a_legacy=LegacyDefinition(name='geometry_optimization_type')) + + input_energy_difference_tolerance = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + The input energy difference tolerance criterion. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='input_energy_difference_tolerance')) + + input_force_maximum_tolerance = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='newton', + description=''' + The input maximum net force tolerance criterion. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='input_force_maximum_tolerance')) + + final_energy_difference = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + The difference in the energy between the last two steps during optimization. + ''', + a_search=Search(), + a_legacy=LegacyDefinition(name='final_energy_difference')) + + final_force_maximum = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='newton', + description=''' + The maximum net force in the last optimization step. + ''', + a_legacy=LegacyDefinition(name='final_force_maximum')) + + optimization_steps = Quantity( + type=int, + shape=[], + description=''' + Number of optimization steps. + ''', + a_legacy=LegacyDefinition(name='optimization_steps')) + + +class Phonon(MSection): + ''' + Section containing the results of a phonon workflow. + ''' + + m_def = Section( + validate=False, + a_legacy=LegacyDefinition(name='section_phonon')) + + force_calculator = Quantity( + type=str, + shape=[], + description=''' + Name of the program used to calculate the forces. + ''', + a_legacy=LegacyDefinition(name='force_calculator')) + + mesh_density = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='1 / meter ** 3', + description=''' + Density of the k-mesh for sampling. + ''', + a_search=Search(), + a_legacy=LegacyDefinition(name='mesh_density')) + + n_imaginary_frequencies = Quantity( + type=int, + shape=[], + description=''' + Number of modes with imaginary frequencies. + ''', + a_search=Search(), + a_legacy=LegacyDefinition(name='n_imaginary_frequencies')) + + random_displacements = Quantity( + type=bool, + shape=[], + description=''' + Identifies if displacements are made randomly. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='random_displacements')) + + with_non_analytic_correction = Quantity( + type=bool, + shape=[], + description=''' + Identifies if non-analytical term corrections are applied to dynamical matrix. + ''', + categories=[Unused], + a_search=Search(), + a_legacy=LegacyDefinition(name='with_non_analytic_correction')) + + with_grueneisen_parameters = Quantity( + type=bool, + shape=[], + description=''' + Identifies if Grueneisen parameters are calculated. + ''', + categories=[Unused], + a_search=Search(), + a_legacy=LegacyDefinition(name='with_grueneisen_parameters')) + + +class Elastic(MSection): + ''' + Section containing the results of an elastic workflow. + ''' + + m_def = Section( + validate=False, + a_legacy=LegacyDefinition(name='section_elastic')) + + energy_stress_calculator = Quantity( + type=str, + shape=[], + description=''' + Name of program used to calculate energy or stress. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='energy_stress_calculator')) + + elastic_calculation_method = Quantity( + type=str, + shape=[], + description=''' + Method used to calculate elastic constants, can either be energy or stress. + ''', + a_legacy=LegacyDefinition(name='elastic_calculation_method')) + + elastic_constants_order = Quantity( + type=int, + shape=[], + description=''' + Order of the calculated elastic constants. + ''', + a_search=Search(), + a_legacy=LegacyDefinition(name='elastic_constants_order')) + + is_mechanically_stable = Quantity( + type=bool, + shape=[], + description=''' + Indicates if structure is mechanically stable from the calculated values of the + elastic constants. + ''', + a_search=Search(), + a_legacy=LegacyDefinition(name='is_mechanically_stable')) + + fitting_error_maximum = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Maximum error in polynomial fit. + ''', + a_legacy=LegacyDefinition(name='fitting_error_maximum')) + + strain_maximum = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Maximum strain applied to crystal. + ''', + a_legacy=LegacyDefinition(name='strain_maximum')) + + +class MolecularDynamics(MSection): + ''' + Section containing results of molecular dynamics workflow. + ''' + + m_def = Section( + validate=False, + a_legacy=LegacyDefinition(name='section_molecular_dynamics')) + + finished_normally = Quantity( + type=bool, + shape=[], + description=''' + Indicates if calculation terminated normally. + ''', + a_legacy=LegacyDefinition(name='finished_normally')) + + with_trajectory = Quantity( + type=bool, + shape=[], + description=''' + Indicates if calculation includes trajectory data. + ''', + a_search=Search(), + a_legacy=LegacyDefinition(name='with_trajectory')) + + with_thermodynamics = Quantity( + type=bool, + shape=[], + description=''' + Indicates if calculation contains thermodynamic data. + ''', + a_search=Search(), + a_legacy=LegacyDefinition(name='with_thermodynamics')) + + +class Workflow(MSection): + ''' + Section containing the results of a workflow. + ''' + + m_def = Section( + validate=False, + a_legacy=LegacyDefinition(name='section_workflow')) + + workflow_type = Quantity( + type=str, + shape=[], + description=''' + The type of calculation workflow. Can be one of geometry_optimization, elastic, + phonon, molecular_dynamics. + ''', + a_search=Search(), + a_legacy=LegacyDefinition(name='workflow_type')) + + calculation_result_ref = Quantity( + type=Reference(SectionProxy('SingleConfigurationCalculation')), + shape=[], + description=''' + Reference to calculation result. In the case of geometry_optimization and + molecular dynamics, this corresponds to the final step in the simulation. For the + rest of the workflow types, it refers to the original system. + ''', + categories=[FastAccess], + a_legacy=LegacyDefinition(name='calculation_result_ref')) + + calculations_ref = Quantity( + type=Reference(SectionProxy('SingleConfigurationCalculation')), + shape=['optimization_steps'], + description=''' + List of references to each section_single_configuration_calculation in the + simulation. + ''', + a_legacy=LegacyDefinition(name='calculations_ref')) + + section_geometry_optimization = SubSection( + sub_section=SectionProxy('GeometryOptimization'), + repeats=False, + categories=[FastAccess], + a_legacy=LegacyDefinition(name='section_geometry_optimization')) + + section_phonon = SubSection( + sub_section=SectionProxy('Phonon'), + repeats=False, + categories=[FastAccess], + a_legacy=LegacyDefinition(name='section_phonon')) + + section_elastic = SubSection( + sub_section=SectionProxy('Elastic'), + repeats=False, + a_legacy=LegacyDefinition(name='section_elastic')) + + section_molecular_dynamics = SubSection( + sub_section=SectionProxy('MolecularDynamics'), + repeats=False, + a_legacy=LegacyDefinition(name='section_molecular_dynamics')) + + +class ResponseContext(MSection): + ''' + The top level context containing the reponse to an api query, when using jsonAPI they + are tipically in the meta part + ''' + + m_def = Section( + aliases=['response_context'], + validate=False, + a_legacy=LegacyDefinition(name='response_context')) + + shortened_meta_info = Quantity( + type=str, + shape=[], + description=''' + A meta info whose corresponding data has been shortened + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='shortened_meta_info')) + + section_response_message = SubSection( + sub_section=SectionProxy('ResponseMessage'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_response_message')) + + +class AtomType(MSection): + ''' + Section describing a type of atom in the system. + ''' + + m_def = Section( + aliases=['section_atom_type'], + validate=False, + a_legacy=LegacyDefinition(name='section_atom_type')) + + atom_type_charge = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='coulomb', + description=''' + Charge of the atom type. + ''', + a_legacy=LegacyDefinition(name='atom_type_charge')) + + atom_type_mass = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='kilogram', + description=''' + Mass of the atom type. + ''', + a_legacy=LegacyDefinition(name='atom_type_mass')) + + atom_type_name = Quantity( + type=str, + shape=[], + description=''' + Name (label) of the atom type. + ''', + a_legacy=LegacyDefinition(name='atom_type_name')) + + +class Constraint(MSection): + ''' + Section describing a constraint between arbitrary atoms. + ''' + + m_def = Section( + aliases=['section_constraint'], + validate=False, + a_legacy=LegacyDefinition(name='section_constraint')) + + constraint_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_constraints', 'number_of_atoms_per_constraint'], + description=''' + List of the indexes involved in this constraint. The fist atom has index 1, the + last number_of_topology_atoms. + ''', + a_legacy=LegacyDefinition(name='constraint_atoms')) + + constraint_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this constraint type. Valid names are described in the + [constraint\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/constraint-kind). + ''', + a_legacy=LegacyDefinition(name='constraint_kind')) + + constraint_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit constraint parameters for this kind of constraint (depending on the + constraint type, some might be given implicitly through other means). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='constraint_parameters')) + + number_of_atoms_per_constraint = Quantity( + type=int, + shape=[], + description=''' + Number of atoms involved in this constraint. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_atoms_per_constraint')) + + number_of_constraints = Quantity( + type=int, + shape=[], + description=''' + Number of constraints of this type. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_constraints')) + + +class DftPlusUOrbital(MSection): + ''' + Section for DFT+U-settings of a single orbital + ''' + + m_def = Section( + aliases=['section_dft_plus_u_orbital'], + validate=False, + a_legacy=LegacyDefinition(name='section_dft_plus_u_orbital')) + + dft_plus_u_orbital_atom = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + DFT+U-orbital setting: atom index (references index of atom_labels/atom_positions) + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='dft_plus_u_orbital_atom')) + + dft_plus_u_orbital_J = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + DFT+U-orbital setting: value J (exchange interaction) + ''', + categories=[EnergyValue, Unused], + a_legacy=LegacyDefinition(name='dft_plus_u_orbital_J')) + + dft_plus_u_orbital_label = Quantity( + type=str, + shape=[], + description=''' + DFT+U-orbital setting: orbital label (normally (n,l)), notation: '3d', '4f', ... + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='dft_plus_u_orbital_label')) + + dft_plus_u_orbital_U_effective = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + DFT+U-orbital setting: value U_{effective} (U-J), if implementation uses it + ''', + categories=[EnergyValue, Unused], + a_legacy=LegacyDefinition(name='dft_plus_u_orbital_U_effective')) + + dft_plus_u_orbital_U = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + DFT+U-orbital setting: value U (on-site Coulomb interaction) + ''', + categories=[EnergyValue, Unused], + a_legacy=LegacyDefinition(name='dft_plus_u_orbital_U')) + + +class ExcitedStates(MSection): + ''' + Excited states properties. + ''' + + m_def = Section( + aliases=['section_excited_states'], + validate=False, + a_legacy=LegacyDefinition(name='section_excited_states')) + + excitation_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_excited_states'], + description=''' + Excitation energies. + ''', + categories=[EnergyValue], + a_legacy=LegacyDefinition(name='excitation_energies')) + + number_of_excited_states = Quantity( + type=int, + shape=[], + description=''' + Number of excited states. + ''', + a_legacy=LegacyDefinition(name='number_of_excited_states')) + + oscillator_strengths = Quantity( + type=np.dtype(np.float64), + shape=['number_of_excited_states'], + description=''' + Excited states oscillator strengths. + ''', + a_legacy=LegacyDefinition(name='oscillator_strengths')) + + transition_dipole_moments = Quantity( + type=np.dtype(np.float64), + shape=['number_of_excited_states', 3], + description=''' + Transition dipole moments. + ''', + a_legacy=LegacyDefinition(name='transition_dipole_moments')) + + +class Interaction(MSection): + ''' + Section containing the description of a bonded interaction between arbitrary atoms. + ''' + + m_def = Section( + aliases=['section_interaction'], + validate=False, + a_legacy=LegacyDefinition(name='section_interaction')) + + interaction_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_interactions', 'number_of_atoms_per_interaction'], + description=''' + List of the indexes involved in this interaction. The fist atom has index 1, the + last atom index number_of_topology_atoms. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='interaction_atoms')) + + interaction_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this interaction type. Valid names are described in the + [interaction\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/interaction-kind). + ''', + a_legacy=LegacyDefinition(name='interaction_kind')) + + interaction_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit interaction parameters for this kind of interaction (depending on the + interaction_kind some might be given implicitly through other means). + ''', + a_legacy=LegacyDefinition(name='interaction_parameters')) + + number_of_atoms_per_interaction = Quantity( + type=int, + shape=[], + description=''' + Number of atoms involved in this interaction. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_atoms_per_interaction')) + + number_of_interactions = Quantity( + type=int, + shape=[], + description=''' + Number of interactions of this type. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_interactions')) + + +class MethodBasisSet(MSection): + ''' + This section contains the definition of the basis sets that are defined independently + of the atomic configuration. + ''' + + m_def = Section( + aliases=['section_method_basis_set'], + validate=False, + a_legacy=LegacyDefinition(name='section_method_basis_set')) + + mapping_section_method_basis_set_atom_centered = Quantity( + type=np.dtype(np.int64), + shape=['number_of_basis_sets_atom_centered', 2], + description=''' + Reference to an atom-centered basis set defined in section_basis_set_atom_centered + and to the atom kind as defined in section_method_atom_kind. + ''', + a_legacy=LegacyDefinition(name='mapping_section_method_basis_set_atom_centered')) + + mapping_section_method_basis_set_cell_associated = Quantity( + type=Reference(SectionProxy('BasisSetCellDependent')), + shape=[], + description=''' + Reference to a cell-associated basis set. + ''', + a_legacy=LegacyDefinition(name='mapping_section_method_basis_set_cell_associated')) + + method_basis_set_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the use of the basis set, i.e, if it used for expanding a + wavefunction or an electron density. Allowed values are listed in the + [basis\\_set\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/basis-set-kind). + ''', + a_legacy=LegacyDefinition(name='method_basis_set_kind')) + + number_of_basis_sets_atom_centered = Quantity( + type=int, + shape=[], + description=''' + String describing the use of the basis set, i.e, if it used for expanding a + wavefunction or an electron density. Allowed values are listed in the + [basis\\_set\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/basis-set-kind). + ''', + a_legacy=LegacyDefinition(name='number_of_basis_sets_atom_centered')) + + +class MoleculeConstraint(MSection): + ''' + Section describing a constraint between atoms within a molecule. + ''' + + m_def = Section( + aliases=['section_molecule_constraint'], + validate=False, + a_legacy=LegacyDefinition(name='section_molecule_constraint')) + + molecule_constraint_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_molecule_constraints', 'number_of_atoms_per_molecule_constraint'], + description=''' + List of the indexes involved in this constraint. The fist atom has index 1, the + last index is number_of_atoms_in_molecule. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='molecule_constraint_atoms')) + + molecule_constraint_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this constraint type. Valid names are described in the + [constraint\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/constraint-kind). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='molecule_constraint_kind')) + + molecule_constraint_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit constraint parameters for this kind of constraint (depending on the + constraint type some might be given implicitly through other means). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='molecule_constraint_parameters')) + + number_of_atoms_per_molecule_constraint = Quantity( + type=int, + shape=[], + description=''' + Number of atoms, in this molecule, involved in this constraint. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_atoms_per_molecule_constraint')) + + number_of_molecule_constraints = Quantity( + type=int, + shape=[], + description=''' + Number of constraints of this type. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_molecule_constraints')) + + +class MoleculeInteraction(MSection): + ''' + Section describing a bonded interaction between atoms within a molecule. + ''' + + m_def = Section( + aliases=['section_molecule_interaction'], + validate=False, + a_legacy=LegacyDefinition(name='section_molecule_interaction')) + + molecule_interaction_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_molecule_interactions', 'number_of_atoms_per_molecule_interaction'], + description=''' + List of the indexes involved in this bonded interaction within a molecule. The + first atom has index 1, the last index is number_of_atoms_in_. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='molecule_interaction_atoms')) + + molecule_interaction_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this interaction type, used for bonded interactions for + atoms in a molecule. Valid names are described in the [interaction\\_kind wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/interaction-kind). + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='molecule_interaction_kind')) + + molecule_interaction_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit interaction parameters for this kind of interaction (depending on the + interaction type some might be given implicitly through other means), used for + bonded interactions for atoms in a molecule. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='molecule_interaction_parameters')) + + number_of_atoms_per_molecule_interaction = Quantity( + type=int, + shape=[], + description=''' + Number of atoms, in this molecule, involved in this interaction. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_atoms_per_molecule_interaction')) + + number_of_molecule_interactions = Quantity( + type=int, + shape=[], + description=''' + Number of bonded interactions of this type. + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_molecule_interactions')) + + +class MoleculeType(MSection): + ''' + Section describing a type of molecule in the system. + ''' + + m_def = Section( + aliases=['section_molecule_type'], + validate=False, + a_legacy=LegacyDefinition(name='section_molecule_type')) + + atom_in_molecule_charge = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms_in_molecule'], + unit='coulomb', + description=''' + Charge of each atom in the molecule. + ''', + categories=[SettingsAtomInMolecule], + a_legacy=LegacyDefinition(name='atom_in_molecule_charge')) + + atom_in_molecule_name = Quantity( + type=str, + shape=['number_of_atoms_in_molecule'], + description=''' + Name (label) of each atom in the molecule. + ''', + categories=[SettingsAtomInMolecule], + a_legacy=LegacyDefinition(name='atom_in_molecule_name')) + + atom_in_molecule_to_atom_type_ref = Quantity( + type=Reference(SectionProxy('AtomType')), + shape=['number_of_atoms_in_molecule'], + description=''' + Reference to the atom type of each atom in the molecule. + ''', + categories=[SettingsAtomInMolecule], + a_legacy=LegacyDefinition(name='atom_in_molecule_to_atom_type_ref')) + + molecule_type_name = Quantity( + type=str, + shape=[], + description=''' + Name of the molecule. + ''', + a_legacy=LegacyDefinition(name='molecule_type_name')) + + number_of_atoms_in_molecule = Quantity( + type=int, + shape=[], + description=''' + Number of atoms in this molecule. + ''', + a_legacy=LegacyDefinition(name='number_of_atoms_in_molecule')) + + section_molecule_constraint = SubSection( + sub_section=SectionProxy('MoleculeConstraint'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_molecule_constraint')) + + section_molecule_interaction = SubSection( + sub_section=SectionProxy('MoleculeInteraction'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_molecule_interaction')) + + +class ResponseMessage(MSection): + ''' + Messages outputted by the program formatting the data in the current response + ''' + + m_def = Section( + aliases=['section_response_message'], + validate=False, + a_legacy=LegacyDefinition(name='section_response_message')) + + response_message_count = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + How many times this message was repeated + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='response_message_count')) + + response_message_level = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + level of the message: 0 fatal, 1 error, 2 warning, 3 debug + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='response_message_level')) + + response_message = Quantity( + type=str, + shape=[], + description=''' + Message outputted by the program formatting the data in the current format + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='response_message')) + + +class SoapCoefficients(MSection): + ''' + Stores the soap coefficients for the pair of atoms given in + soap_coefficients_atom_pair. + ''' + + m_def = Section( + aliases=['section_soap_coefficients'], + validate=False, + a_legacy=LegacyDefinition(name='section_soap_coefficients')) + + number_of_soap_coefficients = Quantity( + type=int, + shape=[], + description=''' + number of soap coefficients + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='number_of_soap_coefficients')) + + soap_coefficients_atom_pair = Quantity( + type=str, + shape=[], + description=''' + Pair of atoms described in the current section + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='soap_coefficients_atom_pair')) + + soap_coefficients = Quantity( + type=np.dtype(np.float64), + shape=['number_of_soap_coefficients'], + description=''' + Compressed coefficient of the soap descriptor for the atom pair + soap_coefficients_atom_pair + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='soap_coefficients')) + + +class Soap(MSection): + ''' + Stores a soap descriptor for this configuration. + ''' + + m_def = Section( + aliases=['section_soap'], + validate=False, + a_legacy=LegacyDefinition(name='section_soap')) + + soap_angular_basis_L = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + angular basis L + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_angular_basis_L')) + + soap_angular_basis_type = Quantity( + type=str, + shape=[], + description=''' + angular basis type + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_angular_basis_type')) + + soap_kernel_adaptor = Quantity( + type=str, + shape=[], + description=''' + kernel adaptor + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_kernel_adaptor')) + + soap_parameters_gid = Quantity( + type=str, + shape=[], + description=''' + Unique checksum of all the soap parameters (all those with abstract type + soap_parameter) with prefix psoap + ''', + categories=[Unused], + a_legacy=LegacyDefinition(name='soap_parameters_gid')) + + soap_radial_basis_integration_steps = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + radial basis integration steps + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_radial_basis_integration_steps')) + + soap_radial_basis_mode = Quantity( + type=str, + shape=[], + description=''' + radial basis mode + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_radial_basis_mode')) + + soap_radial_basis_n = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + radial basis N + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_radial_basis_n')) + + soap_radial_basis_sigma = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + radial basis sigma + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_radial_basis_sigma')) + + soap_radial_basis_type = Quantity( + type=str, + shape=[], + description=''' + radial basis type + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_radial_basis_type')) + + soap_radial_cutoff_center_weight = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + radial cutoff center weight + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_radial_cutoff_center_weight')) + + soap_radial_cutoff_rc_width = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + radial cutoff width + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_radial_cutoff_rc_width')) + + soap_radial_cutoff_rc = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + radial cutoff + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_radial_cutoff_rc')) + + soap_radial_cutoff_type = Quantity( + type=str, + shape=[], + description=''' + radial cutoff type + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_radial_cutoff_type')) + + soap_spectrum_2l1_norm = Quantity( + type=bool, + shape=[], + description=''' + 2l1 norm spectrum + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_spectrum_2l1_norm')) + + soap_spectrum_global = Quantity( + type=bool, + shape=[], + description=''' + global spectrum + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_spectrum_global')) + + soap_spectrum_gradients = Quantity( + type=bool, + shape=[], + description=''' + gradients in specturm + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_spectrum_gradients')) + + soap_type_list = Quantity( + type=str, + shape=[], + description=''' + Type list + ''', + categories=[SoapParameter, Unused], + a_legacy=LegacyDefinition(name='soap_type_list')) + + section_soap_coefficients = SubSection( + sub_section=SectionProxy('SoapCoefficients'), + repeats=True, + categories=[Unused], + a_legacy=LegacyDefinition(name='section_soap_coefficients')) + + +class Topology(MSection): + ''' + Section containing the definition of topology (connectivity among atoms in force + fileds), force field, and constraints of a system. + ''' + + m_def = Section( + aliases=['section_topology'], + validate=False, + a_legacy=LegacyDefinition(name='section_topology')) + + atom_to_molecule = Quantity( + type=np.dtype(np.int32), + shape=['number_of_topology_atoms', 2], + description=''' + Table mapping atom to molecules: the first column is the index of the molecule and + the second column the index of the atom, signifying that the atom in the second + column belongs to the molecule in the first column in the same row. + ''', + a_legacy=LegacyDefinition(name='atom_to_molecule')) + + molecule_to_molecule_type_map = Quantity( + type=Reference(SectionProxy('MoleculeType')), + shape=['number_of_topology_molecules'], + description=''' + Mapping from molecules to molecule types. + ''', + a_legacy=LegacyDefinition(name='molecule_to_molecule_type_map')) + + number_of_topology_atoms = Quantity( + type=int, + shape=[], + description=''' + Number of atoms in the system described by this topology. + ''', + a_legacy=LegacyDefinition(name='number_of_topology_atoms')) + + number_of_topology_molecules = Quantity( + type=int, + shape=[], + description=''' + Number of molecules in the system, as described by this topology. + ''', + a_legacy=LegacyDefinition(name='number_of_topology_molecules')) + + topology_force_field_name = Quantity( + type=str, + shape=[], + description=''' + A unique string idenfiying the force field defined in this section. Strategies to + define it are discussed in the + [topology\\_force\\_field\\_name](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/topology-force-field-name). + ''', + a_legacy=LegacyDefinition(name='topology_force_field_name')) + + section_atom_type = SubSection( + sub_section=SectionProxy('AtomType'), + repeats=True, + a_legacy=LegacyDefinition(name='section_atom_type')) + + section_constraint = SubSection( + sub_section=SectionProxy('Constraint'), + repeats=True, + a_legacy=LegacyDefinition(name='section_constraint')) + + section_interaction = SubSection( + sub_section=SectionProxy('Interaction'), + repeats=True, + a_legacy=LegacyDefinition(name='section_interaction')) + + section_molecule_type = SubSection( + sub_section=SectionProxy('MoleculeType'), + repeats=True, + a_legacy=LegacyDefinition(name='section_molecule_type')) + + +m_package.__init_metainfo__() + + +fast_access = FastAccess +accessory_info = AccessoryInfo +atom_forces_type = AtomForcesType +basis_set_description = BasisSetDescription +configuration_core = ConfigurationCore +conserved_quantity = ConservedQuantity +energy_value = EnergyValue +error_estimate_contribution = ErrorEstimateContribution +message_debug = MessageDebug +parsing_message_debug = ParsingMessageDebug +scf_info = ScfInfo +settings_numerical_parameter = SettingsNumericalParameter +settings_physical_parameter = SettingsPhysicalParameter +settings_potential_energy_surface = SettingsPotentialEnergySurface +settings_run = SettingsRun +settings_sampling = SettingsSampling +settings_scf = SettingsScf +settings_smearing = SettingsSmearing +settings_stress_tensor = SettingsStressTensor +stress_tensor_type = StressTensorType +energy_component_per_atom = EnergyComponentPerAtom +energy_component = EnergyComponent +energy_type_reference = EnergyTypeReference +error_estimate = ErrorEstimate +message_info = MessageInfo +parallelization_info = ParallelizationInfo +parsing_message_info = ParsingMessageInfo +program_info = ProgramInfo +settings_geometry_optimization = SettingsGeometryOptimization +settings_k_points = SettingsKPoints +settings_metadynamics = SettingsMetadynamics +settings_molecular_dynamics = SettingsMolecularDynamics +settings_Monte_Carlo = SettingsMonteCarlo +settings_XC = SettingsXC +time_info = TimeInfo +energy_total_potential_per_atom = EnergyTotalPotentialPerAtom +energy_total_potential = EnergyTotalPotential +energy_type_C = EnergyTypeC +energy_type_van_der_Waals = EnergyTypeVanDerWaals +energy_type_XC = EnergyTypeXC +energy_type_X = EnergyTypeX +message_warning = MessageWarning +parsing_message_warning = ParsingMessageWarning +settings_barostat = SettingsBarostat +settings_integrator = SettingsIntegrator +settings_post_hartree_fock = SettingsPostHartreeFock +settings_relativity = SettingsRelativity +settings_self_interaction_correction = SettingsSelfInteractionCorrection +settings_thermostat = SettingsThermostat +settings_van_der_Waals = SettingsVanDerWaals +settings_XC_functional = SettingsXCFunctional +message_error = MessageError +parsing_message_error = ParsingMessageError +settings_coupled_cluster = SettingsCoupledCluster +settings_GW = SettingsGW +settings_MCSCF = SettingsMCSCF +settings_moller_plesset_perturbation_theory = SettingsMollerPlessetPerturbationTheory +settings_multi_reference = SettingsMultiReference +settings_atom_in_molecule = SettingsAtomInMolecule +settings_constraint = SettingsConstraint +settings_interaction = SettingsInteraction +soap_parameter = SoapParameter +archive_context = ArchiveContext +calculation_context = CalculationContext +section_atom_projected_dos = AtomProjectedDos +section_atomic_multipoles = AtomicMultipoles +section_basis_functions_atom_centered = BasisFunctionsAtomCentered +section_basis_set_atom_centered = BasisSetAtomCentered +section_basis_set_cell_dependent = BasisSetCellDependent +section_basis_set = BasisSet +section_restricted_uri = RestrictedUri +section_calculation_to_calculation_refs = CalculationToCalculationRefs +section_calculation_to_folder_refs = CalculationToFolderRefs +section_dos_fingerprint = DosFingerprint +section_dos = Dos +section_eigenvalues = Eigenvalues +section_energy_code_independent = EnergyCodeIndependent +section_energy_van_der_Waals = EnergyVanDerWaals +section_energy_contribution = EnergyContribution +section_frame_sequence_user_quantity = FrameSequenceUserQuantity +section_frame_sequence = FrameSequence +section_gaussian_basis_group = GaussianBasisGroup +section_k_band_normalized = KBandNormalized +section_k_band_segment_normalized = KBandSegmentNormalized +section_k_band_segment = KBandSegment +section_band_gap = BandGap +section_brillouin_zone = BrillouinZone +section_k_band = KBand +section_method_atom_kind = MethodAtomKind +section_method_to_method_refs = MethodToMethodRefs +section_method = Method +section_original_system = OriginalSystem +section_primitive_system = PrimitiveSystem +section_processor_info = ProcessorInfo +section_processor_log_event = ProcessorLogEvent +section_processor_log = ProcessorLog +section_prototype = Prototype +section_run = Run +section_sampling_method = SamplingMethod +section_scf_iteration = ScfIteration +section_single_configuration_calculation = SingleConfigurationCalculation +section_species_projected_dos = SpeciesProjectedDos +section_springer_material = SpringerMaterial +section_springer_id = SpringerId +section_std_system = StdSystem +section_stress_tensor = StressTensor +section_symmetry = Symmetry +section_system_to_system_refs = SystemToSystemRefs +section_system = System +section_thermodynamical_properties = ThermodynamicalProperties +section_volumetric_data = VolumetricData +section_XC_functionals = XCFunctionals +response_context = ResponseContext +section_atom_type = AtomType +section_constraint = Constraint +section_dft_plus_u_orbital = DftPlusUOrbital +section_excited_states = ExcitedStates +section_interaction = Interaction +section_method_basis_set = MethodBasisSet +section_molecule_constraint = MoleculeConstraint +section_molecule_interaction = MoleculeInteraction +section_molecule_type = MoleculeType +section_response_message = ResponseMessage +section_soap_coefficients = SoapCoefficients +section_soap = Soap +section_topology = Topology diff --git a/nomad/datamodel/metainfo/common_experimental.py b/nomad/datamodel/metainfo/common_experimental.py index 09864cd595e496e638ebdd3573a8ad125db23efb..1ce81fa34299993b24f50c78a4d0803a657e0822 100644 --- a/nomad/datamodel/metainfo/common_experimental.py +++ b/nomad/datamodel/metainfo/common_experimental.py @@ -23,7 +23,7 @@ from nomad.metainfo import ( Datetime, JSON) -m_package = Package(name='common_experimental') +m_package = Package(name='experimental_common') class Experiment(MSection): diff --git a/nomad/datamodel/metainfo/common_old.py b/nomad/datamodel/metainfo/common_old.py new file mode 100644 index 0000000000000000000000000000000000000000..cf74b07931bd9533db1d80be7f66d8a9c2063c93 --- /dev/null +++ b/nomad/datamodel/metainfo/common_old.py @@ -0,0 +1,1354 @@ +# +# Copyright The NOMAD Authors. +# +# This file is part of NOMAD. See https://nomad-lab.eu for further info. +# +# 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. +# + +import numpy as np # pylint: disable=unused-import +import typing # pylint: disable=unused-import +from nomad.metainfo import ( # pylint: disable=unused-import + MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy, + Reference +) +from nomad.metainfo.legacy import LegacyDefinition + +from nomad.datamodel.metainfo import public_old as public + +m_package = Package( + name='common_nomadmetainfo_json', + description='None', + a_legacy=LegacyDefinition(name='common.nomadmetainfo.json')) + + +class settings_atom_in_molecule(MCategory): + ''' + Parameters of an atom within a molecule. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_atom_in_molecule')) + + +class settings_constraint(MCategory): + ''' + Some parameters that describe a constraint + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_constraint')) + + +class settings_interaction(MCategory): + ''' + Some parameters that describe a bonded interaction. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_interaction')) + + +class soap_parameter(MCategory): + ''' + A soap parameter + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='soap_parameter')) + + +class response_context(MSection): + ''' + The top level context containing the reponse to an api query, when using jsonAPI they + are tipically in the meta part + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='response_context')) + + shortened_meta_info = Quantity( + type=str, + shape=[], + description=''' + A meta info whose corresponding data has been shortened + ''', + a_legacy=LegacyDefinition(name='shortened_meta_info')) + + section_response_message = SubSection( + sub_section=SectionProxy('section_response_message'), + repeats=True, + a_legacy=LegacyDefinition(name='section_response_message')) + + +class section_atom_type(MSection): + ''' + Section describing a type of atom in the system. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_atom_type')) + + atom_type_charge = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='coulomb', + description=''' + Charge of the atom type. + ''', + a_legacy=LegacyDefinition(name='atom_type_charge')) + + atom_type_mass = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='kilogram', + description=''' + Mass of the atom type. + ''', + a_legacy=LegacyDefinition(name='atom_type_mass')) + + atom_type_name = Quantity( + type=str, + shape=[], + description=''' + Name (label) of the atom type. + ''', + a_legacy=LegacyDefinition(name='atom_type_name')) + + +class section_constraint(MSection): + ''' + Section describing a constraint between arbitrary atoms. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_constraint')) + + constraint_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_constraints', 'number_of_atoms_per_constraint'], + description=''' + List of the indexes involved in this constraint. The fist atom has index 1, the + last number_of_topology_atoms. + ''', + a_legacy=LegacyDefinition(name='constraint_atoms')) + + constraint_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this constraint type. Valid names are described in the + [constraint\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/constraint-kind). + ''', + a_legacy=LegacyDefinition(name='constraint_kind')) + + constraint_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit constraint parameters for this kind of constraint (depending on the + constraint type, some might be given implicitly through other means). + ''', + a_legacy=LegacyDefinition(name='constraint_parameters')) + + number_of_atoms_per_constraint = Quantity( + type=int, + shape=[], + description=''' + Number of atoms involved in this constraint. + ''', + a_legacy=LegacyDefinition(name='number_of_atoms_per_constraint')) + + number_of_constraints = Quantity( + type=int, + shape=[], + description=''' + Number of constraints of this type. + ''', + a_legacy=LegacyDefinition(name='number_of_constraints')) + + +class section_dft_plus_u_orbital(MSection): + ''' + Section for DFT+U-settings of a single orbital + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_dft_plus_u_orbital')) + + dft_plus_u_orbital_atom = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + DFT+U-orbital setting: atom index (references index of atom_labels/atom_positions) + ''', + a_legacy=LegacyDefinition(name='dft_plus_u_orbital_atom')) + + dft_plus_u_orbital_J = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + DFT+U-orbital setting: value J (exchange interaction) + ''', + categories=[public.energy_value], + a_legacy=LegacyDefinition(name='dft_plus_u_orbital_J')) + + dft_plus_u_orbital_label = Quantity( + type=str, + shape=[], + description=''' + DFT+U-orbital setting: orbital label (normally (n,l)), notation: '3d', '4f', ... + ''', + a_legacy=LegacyDefinition(name='dft_plus_u_orbital_label')) + + dft_plus_u_orbital_U_effective = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + DFT+U-orbital setting: value U_{effective} (U-J), if implementation uses it + ''', + categories=[public.energy_value], + a_legacy=LegacyDefinition(name='dft_plus_u_orbital_U_effective')) + + dft_plus_u_orbital_U = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + DFT+U-orbital setting: value U (on-site Coulomb interaction) + ''', + categories=[public.energy_value], + a_legacy=LegacyDefinition(name='dft_plus_u_orbital_U')) + + +class section_excited_states(MSection): + ''' + Excited states properties. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_excited_states')) + + excitation_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_excited_states'], + description=''' + Excitation energies. + ''', + categories=[public.energy_value], + a_legacy=LegacyDefinition(name='excitation_energies')) + + number_of_excited_states = Quantity( + type=int, + shape=[], + description=''' + Number of excited states. + ''', + a_legacy=LegacyDefinition(name='number_of_excited_states')) + + oscillator_strengths = Quantity( + type=np.dtype(np.float64), + shape=['number_of_excited_states'], + description=''' + Excited states oscillator strengths. + ''', + a_legacy=LegacyDefinition(name='oscillator_strengths')) + + transition_dipole_moments = Quantity( + type=np.dtype(np.float64), + shape=['number_of_excited_states', 3], + description=''' + Transition dipole moments. + ''', + a_legacy=LegacyDefinition(name='transition_dipole_moments')) + + +class section_interaction(MSection): + ''' + Section containing the description of a bonded interaction between arbitrary atoms. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_interaction')) + + interaction_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_interactions', 'number_of_atoms_per_interaction'], + description=''' + List of the indexes involved in this interaction. The fist atom has index 1, the + last atom index number_of_topology_atoms. + ''', + a_legacy=LegacyDefinition(name='interaction_atoms')) + + interaction_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this interaction type. Valid names are described in the + [interaction\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/interaction-kind). + ''', + a_legacy=LegacyDefinition(name='interaction_kind')) + + interaction_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit interaction parameters for this kind of interaction (depending on the + interaction_kind some might be given implicitly through other means). + ''', + a_legacy=LegacyDefinition(name='interaction_parameters')) + + number_of_atoms_per_interaction = Quantity( + type=int, + shape=[], + description=''' + Number of atoms involved in this interaction. + ''', + a_legacy=LegacyDefinition(name='number_of_atoms_per_interaction')) + + number_of_interactions = Quantity( + type=int, + shape=[], + description=''' + Number of interactions of this type. + ''', + a_legacy=LegacyDefinition(name='number_of_interactions')) + + +class section_method_basis_set(MSection): + ''' + This section contains the definition of the basis sets that are defined independently + of the atomic configuration. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_method_basis_set')) + + mapping_section_method_basis_set_atom_centered = Quantity( + type=np.dtype(np.int64), + shape=['number_of_basis_sets_atom_centered', 2], + description=''' + Reference to an atom-centered basis set defined in section_basis_set_atom_centered + and to the atom kind as defined in section_method_atom_kind. + ''', + a_legacy=LegacyDefinition(name='mapping_section_method_basis_set_atom_centered')) + + mapping_section_method_basis_set_cell_associated = Quantity( + type=public.section_basis_set_cell_dependent, + shape=[], + description=''' + Reference to a cell-associated basis set. + ''', + a_legacy=LegacyDefinition(name='mapping_section_method_basis_set_cell_associated')) + + method_basis_set_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the use of the basis set, i.e, if it used for expanding a + wavefunction or an electron density. Allowed values are listed in the + [basis\\_set\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/basis-set-kind). + ''', + a_legacy=LegacyDefinition(name='method_basis_set_kind')) + + number_of_basis_sets_atom_centered = Quantity( + type=int, + shape=[], + description=''' + String describing the use of the basis set, i.e, if it used for expanding a + wavefunction or an electron density. Allowed values are listed in the + [basis\\_set\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/basis-set-kind). + ''', + a_legacy=LegacyDefinition(name='number_of_basis_sets_atom_centered')) + + +class section_molecule_constraint(MSection): + ''' + Section describing a constraint between atoms within a molecule. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_molecule_constraint')) + + molecule_constraint_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_molecule_constraints', 'number_of_atoms_per_molecule_constraint'], + description=''' + List of the indexes involved in this constraint. The fist atom has index 1, the + last index is number_of_atoms_in_molecule. + ''', + a_legacy=LegacyDefinition(name='molecule_constraint_atoms')) + + molecule_constraint_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this constraint type. Valid names are described in the + [constraint\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/constraint-kind). + ''', + a_legacy=LegacyDefinition(name='molecule_constraint_kind')) + + molecule_constraint_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit constraint parameters for this kind of constraint (depending on the + constraint type some might be given implicitly through other means). + ''', + a_legacy=LegacyDefinition(name='molecule_constraint_parameters')) + + number_of_atoms_per_molecule_constraint = Quantity( + type=int, + shape=[], + description=''' + Number of atoms, in this molecule, involved in this constraint. + ''', + a_legacy=LegacyDefinition(name='number_of_atoms_per_molecule_constraint')) + + number_of_molecule_constraints = Quantity( + type=int, + shape=[], + description=''' + Number of constraints of this type. + ''', + a_legacy=LegacyDefinition(name='number_of_molecule_constraints')) + + +class section_molecule_interaction(MSection): + ''' + Section describing a bonded interaction between atoms within a molecule. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_molecule_interaction')) + + molecule_interaction_atoms = Quantity( + type=np.dtype(np.int32), + shape=['number_of_molecule_interactions', 'number_of_atoms_per_molecule_interaction'], + description=''' + List of the indexes involved in this bonded interaction within a molecule. The + first atom has index 1, the last index is number_of_atoms_in_. + ''', + a_legacy=LegacyDefinition(name='molecule_interaction_atoms')) + + molecule_interaction_kind = Quantity( + type=str, + shape=[], + description=''' + Short and unique name for this interaction type, used for bonded interactions for + atoms in a molecule. Valid names are described in the [interaction\\_kind wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/interaction-kind). + ''', + a_legacy=LegacyDefinition(name='molecule_interaction_kind')) + + molecule_interaction_parameters = Quantity( + type=typing.Any, + shape=[], + description=''' + Explicit interaction parameters for this kind of interaction (depending on the + interaction type some might be given implicitly through other means), used for + bonded interactions for atoms in a molecule. + ''', + a_legacy=LegacyDefinition(name='molecule_interaction_parameters')) + + number_of_atoms_per_molecule_interaction = Quantity( + type=int, + shape=[], + description=''' + Number of atoms, in this molecule, involved in this interaction. + ''', + a_legacy=LegacyDefinition(name='number_of_atoms_per_molecule_interaction')) + + number_of_molecule_interactions = Quantity( + type=int, + shape=[], + description=''' + Number of bonded interactions of this type. + ''', + a_legacy=LegacyDefinition(name='number_of_molecule_interactions')) + + +class section_molecule_type(MSection): + ''' + Section describing a type of molecule in the system. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_molecule_type')) + + atom_in_molecule_charge = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atoms_in_molecule'], + unit='coulomb', + description=''' + Charge of each atom in the molecule. + ''', + categories=[settings_atom_in_molecule], + a_legacy=LegacyDefinition(name='atom_in_molecule_charge')) + + atom_in_molecule_name = Quantity( + type=str, + shape=['number_of_atoms_in_molecule'], + description=''' + Name (label) of each atom in the molecule. + ''', + categories=[settings_atom_in_molecule], + a_legacy=LegacyDefinition(name='atom_in_molecule_name')) + + atom_in_molecule_to_atom_type_ref = Quantity( + type=Reference(SectionProxy('section_atom_type')), + shape=['number_of_atoms_in_molecule'], + description=''' + Reference to the atom type of each atom in the molecule. + ''', + categories=[settings_atom_in_molecule], + a_legacy=LegacyDefinition(name='atom_in_molecule_to_atom_type_ref')) + + molecule_type_name = Quantity( + type=str, + shape=[], + description=''' + Name of the molecule. + ''', + a_legacy=LegacyDefinition(name='molecule_type_name')) + + number_of_atoms_in_molecule = Quantity( + type=int, + shape=[], + description=''' + Number of atoms in this molecule. + ''', + a_legacy=LegacyDefinition(name='number_of_atoms_in_molecule')) + + section_molecule_constraint = SubSection( + sub_section=SectionProxy('section_molecule_constraint'), + repeats=True, + a_legacy=LegacyDefinition(name='section_molecule_constraint')) + + section_molecule_interaction = SubSection( + sub_section=SectionProxy('section_molecule_interaction'), + repeats=True, + a_legacy=LegacyDefinition(name='section_molecule_interaction')) + + +class section_response_message(MSection): + ''' + Messages outputted by the program formatting the data in the current response + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_response_message')) + + response_message_count = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + How many times this message was repeated + ''', + a_legacy=LegacyDefinition(name='response_message_count')) + + response_message_level = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + level of the message: 0 fatal, 1 error, 2 warning, 3 debug + ''', + a_legacy=LegacyDefinition(name='response_message_level')) + + response_message = Quantity( + type=str, + shape=[], + description=''' + Message outputted by the program formatting the data in the current format + ''', + a_legacy=LegacyDefinition(name='response_message')) + + +class section_soap_coefficients(MSection): + ''' + Stores the soap coefficients for the pair of atoms given in + soap_coefficients_atom_pair. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_soap_coefficients')) + + number_of_soap_coefficients = Quantity( + type=int, + shape=[], + description=''' + number of soap coefficients + ''', + a_legacy=LegacyDefinition(name='number_of_soap_coefficients')) + + soap_coefficients_atom_pair = Quantity( + type=str, + shape=[], + description=''' + Pair of atoms described in the current section + ''', + a_legacy=LegacyDefinition(name='soap_coefficients_atom_pair')) + + soap_coefficients = Quantity( + type=np.dtype(np.float64), + shape=['number_of_soap_coefficients'], + description=''' + Compressed coefficient of the soap descriptor for the atom pair + soap_coefficients_atom_pair + ''', + a_legacy=LegacyDefinition(name='soap_coefficients')) + + +class section_soap(MSection): + ''' + Stores a soap descriptor for this configuration. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_soap')) + + soap_angular_basis_L = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + angular basis L + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_angular_basis_L')) + + soap_angular_basis_type = Quantity( + type=str, + shape=[], + description=''' + angular basis type + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_angular_basis_type')) + + soap_kernel_adaptor = Quantity( + type=str, + shape=[], + description=''' + kernel adaptor + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_kernel_adaptor')) + + soap_parameters_gid = Quantity( + type=str, + shape=[], + description=''' + Unique checksum of all the soap parameters (all those with abstract type + soap_parameter) with prefix psoap + ''', + a_legacy=LegacyDefinition(name='soap_parameters_gid')) + + soap_radial_basis_integration_steps = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + radial basis integration steps + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_radial_basis_integration_steps')) + + soap_radial_basis_mode = Quantity( + type=str, + shape=[], + description=''' + radial basis mode + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_radial_basis_mode')) + + soap_radial_basis_n = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + radial basis N + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_radial_basis_n')) + + soap_radial_basis_sigma = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + radial basis sigma + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_radial_basis_sigma')) + + soap_radial_basis_type = Quantity( + type=str, + shape=[], + description=''' + radial basis type + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_radial_basis_type')) + + soap_radial_cutoff_center_weight = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + radial cutoff center weight + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_radial_cutoff_center_weight')) + + soap_radial_cutoff_rc_width = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + radial cutoff width + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_radial_cutoff_rc_width')) + + soap_radial_cutoff_rc = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + radial cutoff + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_radial_cutoff_rc')) + + soap_radial_cutoff_type = Quantity( + type=str, + shape=[], + description=''' + radial cutoff type + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_radial_cutoff_type')) + + soap_spectrum_2l1_norm = Quantity( + type=bool, + shape=[], + description=''' + 2l1 norm spectrum + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_spectrum_2l1_norm')) + + soap_spectrum_global = Quantity( + type=bool, + shape=[], + description=''' + global spectrum + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_spectrum_global')) + + soap_spectrum_gradients = Quantity( + type=bool, + shape=[], + description=''' + gradients in specturm + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_spectrum_gradients')) + + soap_type_list = Quantity( + type=str, + shape=[], + description=''' + Type list + ''', + categories=[soap_parameter], + a_legacy=LegacyDefinition(name='soap_type_list')) + + section_soap_coefficients = SubSection( + sub_section=SectionProxy('section_soap_coefficients'), + repeats=True, + a_legacy=LegacyDefinition(name='section_soap_coefficients')) + + +class section_topology(MSection): + ''' + Section containing the definition of topology (connectivity among atoms in force + fileds), force field, and constraints of a system. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_topology')) + + atom_to_molecule = Quantity( + type=np.dtype(np.int32), + shape=['number_of_topology_atoms', 2], + description=''' + Table mapping atom to molecules: the first column is the index of the molecule and + the second column the index of the atom, signifying that the atom in the second + column belongs to the molecule in the first column in the same row. + ''', + a_legacy=LegacyDefinition(name='atom_to_molecule')) + + molecule_to_molecule_type_map = Quantity( + type=Reference(SectionProxy('section_molecule_type')), + shape=['number_of_topology_molecules'], + description=''' + Mapping from molecules to molecule types. + ''', + a_legacy=LegacyDefinition(name='molecule_to_molecule_type_map')) + + number_of_topology_atoms = Quantity( + type=int, + shape=[], + description=''' + Number of atoms in the system described by this topology. + ''', + a_legacy=LegacyDefinition(name='number_of_topology_atoms')) + + number_of_topology_molecules = Quantity( + type=int, + shape=[], + description=''' + Number of molecules in the system, as described by this topology. + ''', + a_legacy=LegacyDefinition(name='number_of_topology_molecules')) + + topology_force_field_name = Quantity( + type=str, + shape=[], + description=''' + A unique string idenfiying the force field defined in this section. Strategies to + define it are discussed in the + [topology\\_force\\_field\\_name](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/topology-force-field-name). + ''', + a_legacy=LegacyDefinition(name='topology_force_field_name')) + + section_atom_type = SubSection( + sub_section=SectionProxy('section_atom_type'), + repeats=True, + a_legacy=LegacyDefinition(name='section_atom_type')) + + section_constraint = SubSection( + sub_section=SectionProxy('section_constraint'), + repeats=True, + a_legacy=LegacyDefinition(name='section_constraint')) + + section_interaction = SubSection( + sub_section=SectionProxy('section_interaction'), + repeats=True, + a_legacy=LegacyDefinition(name='section_interaction')) + + section_molecule_type = SubSection( + sub_section=SectionProxy('section_molecule_type'), + repeats=True, + a_legacy=LegacyDefinition(name='section_molecule_type')) + + +class section_method(public.section_method): + + m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_method')) + + dft_plus_u_functional = Quantity( + type=str, + shape=[], + description=''' + Type of DFT+U functional (such as DFT/DFT+U double-counting compensation). Valid + names are described in the [dft\\_plus\\_u\\_functional wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/dft- + plus-u-functional). + ''', + a_legacy=LegacyDefinition(name='dft_plus_u_functional')) + + dft_plus_u_projection_type = Quantity( + type=str, + shape=[], + description=''' + DFT+U: Type of orbitals used for projection in order to calculate occupation + numbers. Valid names are described in the [dft\\_plus\\_u\\_projection\\_type wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/dft- + plus-u-projection-type). + ''', + a_legacy=LegacyDefinition(name='dft_plus_u_projection_type')) + + gw_bare_coulomb_cutofftype = Quantity( + type=str, + shape=[], + description=''' + Cutoff type for the calculation of the bare Coulomb potential: none, 0d, 1d, 2d. + See Rozzi et al., PRB 73, 205119 (2006) + ''', + a_legacy=LegacyDefinition(name='gw_bare_coulomb_cutofftype')) + + gw_bare_coulomb_gmax = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='1 / meter', + description=''' + Maximum G for the pw basis for the Coulomb potential. + ''', + a_legacy=LegacyDefinition(name='gw_bare_coulomb_gmax')) + + gw_basis_set = Quantity( + type=str, + shape=[], + description=''' + Auxillary basis set used for non-local operators: mixed - mixed basis set, Kotani + and Schilfgaarde, Solid State Comm. 121, 461 (2002). + ''', + a_legacy=LegacyDefinition(name='gw_basis_set')) + + gw_core_treatment = Quantity( + type=str, + shape=[], + description=''' + It specifies whether the core states are treated in the GW calculation: all - All + electron calculation; val - Valence electron only calculation; vab - Core + electrons are excluded from the mixed product basis; xal - All electron treatment + of the exchange self-energy only + ''', + a_legacy=LegacyDefinition(name='gw_core_treatment')) + + gw_frequency_grid_type = Quantity( + type=str, + shape=[], + description=''' + Frequency integration grid type for the correlational self energy: 'eqdis' - + equidistant frequencies from 0 to freqmax; 'gaulag' - Gauss-Laguerre quadrature + from 0 to infinity; 'gauleg' - Gauss-Legendre quadrature from 0 to freqmax; + 'gaule2' (default) - double Gauss-Legendre quadrature from 0 to freqmax and from + freqmax to infinity. + ''', + a_legacy=LegacyDefinition(name='gw_frequency_grid_type')) + + gw_max_frequency = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Maximum frequency for the calculation of the self energy. + ''', + a_legacy=LegacyDefinition(name='gw_max_frequency')) + + gw_mixed_basis_gmax = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='1 / meter', + description=''' + Cut-off parameter for the truncation of the expansion of the plane waves in the + interstitial region. + ''', + a_legacy=LegacyDefinition(name='gw_mixed_basis_gmax')) + + gw_mixed_basis_lmax = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Maximum l value used for the radial functions within the muffin-tin. + ''', + a_legacy=LegacyDefinition(name='gw_mixed_basis_lmax')) + + gw_mixed_basis_tolerance = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Eigenvalue threshold below which the egenvectors are discarded in the construction + of the radial basis set. + ''', + a_legacy=LegacyDefinition(name='gw_mixed_basis_tolerance')) + + gw_ngridq = Quantity( + type=np.dtype(np.int32), + shape=[3], + description=''' + k/q-point grid size used in the GW calculation. + ''', + a_legacy=LegacyDefinition(name='gw_ngridq')) + + gw_frequency_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Number referring to the frequency used in the calculation of the self energy. + ''', + a_legacy=LegacyDefinition(name='gw_frequency_number')) + + gw_frequency_values = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Values of the frequency used in the calculation of the self energy. + ''', + a_legacy=LegacyDefinition(name='gw_frequency_values')) + + gw_frequency_weights = Quantity( + type=np.dtype(np.float64), + shape=[], + description=''' + Weights of the frequency used in the calculation of the self energy. + ''', + a_legacy=LegacyDefinition(name='gw_frequency_weights')) + + gw_number_of_frequencies = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Number of frequency points used in the calculation of the self energy. + ''', + a_legacy=LegacyDefinition(name='gw_number_of_frequencies')) + + gw_polarizability_number_of_empty_states = Quantity( + type=int, + shape=[], + description=''' + Number of empty states used to compute the polarizability P + ''', + a_legacy=LegacyDefinition(name='gw_polarizability_number_of_empty_states')) + + gw_qp_equation_treatment = Quantity( + type=str, + shape=[], + description=''' + Methods to solve the quasi-particle equation: 'linearization', 'self-consistent' + ''', + a_legacy=LegacyDefinition(name='gw_qp_equation_treatment')) + + gw_screened_coulomb_volume_average = Quantity( + type=str, + shape=[], + description=''' + Type of volume averaging for the dynamically screened Coulomb potential: isotropic + - Simple averaging along a specified direction using only diagonal components of + the dielectric tensor; anisotropic - Anisotropic screening by C. Freysoldt et al., + CPC 176, 1-13 (2007) + ''', + a_legacy=LegacyDefinition(name='gw_screened_coulomb_volume_average')) + + gw_screened_Coulomb = Quantity( + type=str, + shape=[], + description=''' + Model used to calculate the dinamically-screened Coulomb potential: 'rpa' - Full- + frequency random-phase approximation; 'ppm' - Godby-Needs plasmon-pole model Godby + and Needs, Phys. Rev. Lett. 62, 1169 (1989); 'ppm_hl' - Hybertsen and Louie, Phys. + Rev. B 34, 5390 (1986); 'ppm_lh' - von der Linden and P. Horsh, Phys. Rev. B 37, + 8351 (1988); 'ppm_fe' - Farid and Engel, Phys. Rev. B 47,15931 (1993); 'cdm' - + Contour deformation method, Phys. Rev. B 67, 155208 (2003).) + ''', + a_legacy=LegacyDefinition(name='gw_screened_Coulomb')) + + gw_self_energy_c_analytical_continuation = Quantity( + type=str, + shape=[], + description=''' + Models for the correlation self-energy analytical continuation: 'pade' - Pade's + approximant (by H. J. Vidberg and J. W. Serence, J. Low Temp. Phys. 29, 179 + (1977)); 'mpf' - Multi-Pole Fitting (by H. N Rojas, R. W. Godby and R. J. Needs, + Phys. Rev. Lett. 74, 1827 (1995)); 'cd' - contour deformation; 'ra' - real axis + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_c_analytical_continuation')) + + gw_self_energy_c_number_of_empty_states = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Number of empty states to be used to calculate the correlation self energy. + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_c_number_of_empty_states')) + + gw_self_energy_c_number_of_poles = Quantity( + type=int, + shape=[], + description=''' + Number of poles used in the analytical continuation. + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_c_number_of_poles')) + + gw_self_energy_singularity_treatment = Quantity( + type=str, + shape=[], + description=''' + Treatment of the integrable singular terms in the calculation of the self energy. + Values: 'mpb' - Auxiliary function method by S. Massidda, M. Posternak, and A. + Baldereschi, PRB 48, 5058 (1993); 'crg' - Auxiliary function method by P. Carrier, + S. Rohra, and A. Goerling, PRB 75, 205126 (2007). + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_singularity_treatment')) + + gw_starting_point = Quantity( + type=str, + shape=[], + description=''' + Exchange-correlation functional of the ground-state calculation. See XC_functional + list at https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- + functional + ''', + a_legacy=LegacyDefinition(name='gw_starting_point')) + + gw_type_test = Quantity( + type=str, + shape=[], + description=''' + GW methodology: exciting test variable + ''', + a_legacy=LegacyDefinition(name='gw_type_test')) + + gw_type = Quantity( + type=str, + shape=[], + description=''' + GW methodology: G0W0; ev-scGW: (eigenvalues self-consistent GW) – Phys.Rev.B 34, + 5390 (1986); qp-scGW: (quasi-particle self-consistent GW) – Phys. Rev. Lett. 96, + 226402 (2006) scGW0: (self-consistent G with fixed W0) – Phys.Rev.B 54, 8411 + (1996); scG0W: (self-consistent W with fixed G0); scGW: (self-consistent GW) – + Phys. Rev. B 88, 075105 (2013) + ''', + a_legacy=LegacyDefinition(name='gw_type')) + + method_to_topology_ref = Quantity( + type=Reference(SectionProxy('section_topology')), + shape=[], + description=''' + Reference to the topology and force fields to be used. + ''', + a_legacy=LegacyDefinition(name='method_to_topology_ref')) + + section_dft_plus_u_orbital = SubSection( + sub_section=SectionProxy('section_dft_plus_u_orbital'), + repeats=True, + a_legacy=LegacyDefinition(name='section_dft_plus_u_orbital')) + + section_method_basis_set = SubSection( + sub_section=SectionProxy('section_method_basis_set'), + repeats=True, + a_legacy=LegacyDefinition(name='section_method_basis_set')) + + +class section_single_configuration_calculation(public.section_single_configuration_calculation): + + m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_single_configuration_calculation')) + + energy_C_mGGA = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Component of the correlation (C) energy at the GGA (or MetaGGA) level using the + self-consistent density of the target XC functional (full unscaled value, i.e., + not scaled due to exact-exchange mixing). + ''', + categories=[public.energy_component, public.energy_value, public.energy_type_C], + a_legacy=LegacyDefinition(name='energy_C_mGGA')) + + energy_reference_fermi = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Fermi energy (separates occupied from unoccupied single-particle states in metals) + ''', + categories=[public.energy_type_reference, public.energy_value], + a_legacy=LegacyDefinition(name='energy_reference_fermi')) + + energy_reference_highest_occupied = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Highest occupied single-particle state energy (in insulators or HOMO energy in + finite systems) + ''', + categories=[public.energy_type_reference, public.energy_value], + a_legacy=LegacyDefinition(name='energy_reference_highest_occupied')) + + energy_reference_lowest_unoccupied = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Lowest unoccupied single-particle state energy (in insulators or LUMO energy in + finite systems) + ''', + categories=[public.energy_type_reference, public.energy_value], + a_legacy=LegacyDefinition(name='energy_reference_lowest_unoccupied')) + + energy_X_mGGA_scaled = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Component of the exchange (X) energy at the GGA (or MetaGGA) level, using the self + consistent density of the target functional, scaled accordingly to the mixing + parameter. + ''', + categories=[public.energy_component, public.energy_value], + a_legacy=LegacyDefinition(name='energy_X_mGGA_scaled')) + + energy_X_mGGA = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Component of the exchange (X) energy at the GGA (or MetaGGA) level using the self + consistent density of the target functional (full unscaled value, i.e., not scaled + due to exact-exchange mixing). + ''', + categories=[public.energy_type_X, public.energy_component, public.energy_value], + a_legacy=LegacyDefinition(name='energy_X_mGGA')) + + gw_fermi_energy = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + GW Fermi energy + ''', + a_legacy=LegacyDefinition(name='gw_fermi_energy')) + + gw_fundamental_gap = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + GW fundamental band gap + ''', + a_legacy=LegacyDefinition(name='gw_fundamental_gap')) + + gw_optical_gap = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + GW optical band gap + ''', + a_legacy=LegacyDefinition(name='gw_optical_gap')) + + gw_self_energy_c = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Diagonal matrix elements of the correlation self-energy + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_c')) + + gw_self_energy_x = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Diagonal matrix elements of the exchange self-energy + ''', + a_legacy=LegacyDefinition(name='gw_self_energy_x')) + + gw_xc_potential = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + unit='joule', + description=''' + Diagonal matrix elements of the exchange-correlation potential + ''', + a_legacy=LegacyDefinition(name='gw_xc_potential')) + + section_excited_states = SubSection( + sub_section=SectionProxy('section_excited_states'), + repeats=True, + a_legacy=LegacyDefinition(name='section_excited_states')) + + +class section_scf_iteration(public.section_scf_iteration): + + m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_scf_iteration')) + + energy_reference_fermi_iteration = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Fermi energy (separates occupied from unoccupied single-particle states in metals) + during the self-consistent field (SCF) iterations. + ''', + categories=[public.energy_type_reference, public.energy_value], + a_legacy=LegacyDefinition(name='energy_reference_fermi_iteration')) + + energy_reference_highest_occupied_iteration = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Highest occupied single-particle state energy (in insulators or HOMO energy in + finite systems) during the self-consistent field (SCF) iterations. + ''', + categories=[public.energy_type_reference, public.energy_value], + a_legacy=LegacyDefinition(name='energy_reference_highest_occupied_iteration')) + + energy_reference_lowest_unoccupied_iteration = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + unit='joule', + description=''' + Lowest unoccupied single-particle state energy (in insulators or LUMO energy in + finite systems) during the self-consistent field (SCF) iterations. + ''', + categories=[public.energy_type_reference, public.energy_value], + a_legacy=LegacyDefinition(name='energy_reference_lowest_unoccupied_iteration')) + + +class section_eigenvalues(public.section_eigenvalues): + + m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_eigenvalues')) + + gw_qp_linearization_prefactor = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], + description=''' + Linearization prefactor + ''', + a_legacy=LegacyDefinition(name='gw_qp_linearization_prefactor')) + + +class section_system(public.section_system): + + m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_system')) + + number_of_electrons = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels'], + description=''' + Number of electrons in system + ''', + categories=[public.configuration_core], + a_legacy=LegacyDefinition(name='number_of_electrons')) + + topology_ref = Quantity( + type=Reference(SectionProxy('section_topology')), + shape=[], + description=''' + Reference to the topology used for this system; if not given, the trivial topology + should be assumed. + ''', + a_legacy=LegacyDefinition(name='topology_ref')) + + is_representative = Quantity( + type=bool, + shape=[], + description=''' + Most systems in a run are only minor variations of each other. Systems marked + representative where chosen to be representative for all systems in the run. + ''', + a_legacy=LegacyDefinition(name='is_representative')) + + section_soap = SubSection( + sub_section=SectionProxy('section_soap'), + repeats=True, + a_legacy=LegacyDefinition(name='section_soap')) + + +class section_run(public.section_run): + + m_def = Section(validate=False, extends_base_section=True, a_legacy=LegacyDefinition(name='section_run')) + + section_topology = SubSection( + sub_section=SectionProxy('section_topology'), + repeats=True, + a_legacy=LegacyDefinition(name='section_topology')) + + +m_package.__init_metainfo__() diff --git a/nomad/datamodel/metainfo/general_qcms.py b/nomad/datamodel/metainfo/common_qcms.py similarity index 100% rename from nomad/datamodel/metainfo/general_qcms.py rename to nomad/datamodel/metainfo/common_qcms.py diff --git a/nomad/datamodel/metainfo/general.py b/nomad/datamodel/metainfo/general.py index 0606de2a91d0b262a2477d9ef161cee4cb28d7d7..3bee89a6a3cdb1d45c6bfdac7906fa458b8266ef 100644 --- a/nomad/datamodel/metainfo/general.py +++ b/nomad/datamodel/metainfo/general.py @@ -16,164 +16,10 @@ # limitations under the License. # -import numpy as np # pylint: disable=unused-import -import typing # pylint: disable=unused-import -from nomad.metainfo import ( # pylint: disable=unused-import - MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy, - Reference -) -from nomad.metainfo.legacy import LegacyDefinition +# This is just for backward compatibility of old imports. All definitions are now in common_dft +from nomad.metainfo import Package -m_package = Package( - name='general_nomadmetainfo_json', - description='None', - a_legacy=LegacyDefinition(name='general.nomadmetainfo.json')) +from .common_dft import * - -class section_entry_info(MSection): - ''' - General information about this entry that is independent from its domain, field, or - used parser - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_entry_info')) - - entry_upload_time = Quantity( - type=np.dtype(np.int64), - shape=[], - description=''' - Upload datetime, given as total number of seconds is the elapsed since the unix - epoch (1 January 1970) - ''', - a_legacy=LegacyDefinition(name='entry_upload_time')) - - entry_uploader_name = Quantity( - type=str, - shape=[], - description=''' - Name of the uploader, given as lastname, firstname. - ''', - a_legacy=LegacyDefinition(name='entry_uploader_name')) - - entry_uploader_id = Quantity( - type=str, - shape=[], - description=''' - The id of the uploader. - ''', - a_legacy=LegacyDefinition(name='entry_uploader_id')) - - upload_id = Quantity( - type=str, - shape=[], - description=''' - Nomad upload id - ''', - a_legacy=LegacyDefinition(name='upload_id')) - - calc_id = Quantity( - type=str, - shape=[], - description=''' - Nomad calc id. - ''', - a_legacy=LegacyDefinition(name='calc_id')) - - calc_hash = Quantity( - type=str, - shape=[], - description=''' - Calculation hash based on raw file contents. - ''', - a_legacy=LegacyDefinition(name='calc_hash')) - - mainfile = Quantity( - type=str, - shape=[], - description=''' - Path to the main file within the upload. - ''', - a_legacy=LegacyDefinition(name='mainfile')) - - parser_name = Quantity( - type=str, - shape=[], - description=''' - Name of the parser used to extract this information. - ''', - a_legacy=LegacyDefinition(name='parser_name')) - - filepaths = Quantity( - type=str, - shape=['number_of_files'], - description=''' - Filepaths of files that belong to this entry, i.e. files in the same directory. - Filepaths are relative to the upload. - ''', - a_legacy=LegacyDefinition(name='filepaths')) - - number_of_files = Quantity( - type=int, - shape=[], - description=''' - Number of files that belong to this entry. - ''', - a_legacy=LegacyDefinition(name='number_of_files')) - - section_archive_processing_info = SubSection( - sub_section=SectionProxy('section_archive_processing_info'), - repeats=True, - a_legacy=LegacyDefinition(name='section_archive_processing_info')) - - -class section_archive_processing_info(MSection): - ''' - Information about the used archive processing steps and their execution. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_archive_processing_info')) - - archive_processor_name = Quantity( - type=str, - shape=[], - description=''' - Name of the applied archive processing program. - ''', - a_legacy=LegacyDefinition(name='archive_processor_name')) - - archive_processor_error = Quantity( - type=str, - shape=[], - description=''' - The main error during execution of the archive processing program that failed the - program. - ''', - a_legacy=LegacyDefinition(name='archive_processor_error')) - - number_of_archive_processor_warnings = Quantity( - type=int, - shape=[], - description=''' - Number of warnings during execution of the archive processing program. - ''', - a_legacy=LegacyDefinition(name='number_of_archive_processor_warnings')) - - archive_processor_warnings = Quantity( - type=str, - shape=['number_of_archive_processor_warnings'], - description=''' - Warnings during execution of the archive processing program. - ''', - a_legacy=LegacyDefinition(name='archive_processor_warnings')) - - archive_processor_status = Quantity( - type=str, - shape=[], - description=''' - Status returned by archive processing program. - ''', - a_legacy=LegacyDefinition(name='archive_processor_status')) - - -m_package.__init_metainfo__() +m_package = Package(name='general_nomadmetainfo_json') diff --git a/nomad/datamodel/metainfo/public.py b/nomad/datamodel/metainfo/public.py index fc30912cc763d2a4b3a88db438fe36e2f2bc05ca..cdf532b9e7ca18bf09312662628bb6ce62a87bcb 100644 --- a/nomad/datamodel/metainfo/public.py +++ b/nomad/datamodel/metainfo/public.py @@ -16,5926 +16,6 @@ # limitations under the License. # -import numpy as np # pylint: disable=unused-import -import typing # pylint: disable=unused-import -from nomad.metainfo import ( # pylint: disable=unused-import - MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy, - Reference, MEnum, derived -) -from nomad.metainfo.search_extension import Search -from nomad.metainfo.legacy import LegacyDefinition +# This is just for backward compatibility of old imports. All definitions are now in common_dft - -m_package = Package( - name='public_nomadmetainfo_json', - description='None', - a_legacy=LegacyDefinition(name='public.nomadmetainfo.json')) - - -class fast_access(MCategory): - ''' - Used to mark archive objects that need to be stored in a fast 2nd-tier storage - medium, because they are frequently accessed via archive API. - - If applied to a sub_section, the section will be added to the fast storage. Currently - this only works for *root* sections that are sub_sections of `EntryArchive`. - - If applied to a reference types quantity, the referenced section will also be added - to the fast storage, regardless if the referenced section has the category or not. - ''' - - m_def = Category() - - -class accessory_info(MCategory): - ''' - Information that *in theory* should not affect the results of the calculations (e.g., - timing). - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='accessory_info')) - - -class atom_forces_type(MCategory): - ''' - The types of forces acting on the atoms (i.e., minus derivatives of the specific type - of energy with respect to the atom position). - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='atom_forces_type')) - - -class basis_set_description(MCategory): - ''' - One of the parts building the basis set of the system (e.g., some atom-centered basis - set, plane-waves or both). - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='basis_set_description')) - - -class configuration_core(MCategory): - ''' - Properties defining the current configuration. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='configuration_core')) - - -class conserved_quantity(MCategory): - ''' - A quantity that is preserved during the time propagation (for example, - kinetic+potential energy during NVE). - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='conserved_quantity')) - - -class energy_value(MCategory): - ''' - This metadata stores an energy value. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='energy_value')) - - -class error_estimate_contribution(MCategory): - ''' - An estimate of a partial quantity contributing to the error for a given quantity. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='error_estimate_contribution')) - - -class message_debug(MCategory): - ''' - A debugging message of the computational program. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='message_debug')) - - -class parsing_message_debug(MCategory): - ''' - This field is used for debugging messages of the parsing program. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='parsing_message_debug')) - - -class scf_info(MCategory): - ''' - Contains information on the self-consistent field (SCF) procedure, i.e. the number of - SCF iterations (number_of_scf_iterations) or a section_scf_iteration section with - detailed information on the SCF procedure of specified quantities. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='scf_info')) - - -class settings_numerical_parameter(MCategory): - ''' - A parameter that can influence the convergence, but not the physics (unlike - settings_physical_parameter) - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_numerical_parameter')) - - -class settings_physical_parameter(MCategory): - ''' - A parameter that defines the physical model used. Use settings_numerical_parameter for - parameters that that influence only the convergence/accuracy. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_physical_parameter')) - - -class settings_potential_energy_surface(MCategory): - ''' - Contains parameters that control the potential energy surface. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_potential_energy_surface')) - - -class settings_run(MCategory): - ''' - Contains parameters that control the whole run (but not the *single configuration - calculation*, see section_single_configuration_calculation). - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_run')) - - -class settings_sampling(MCategory): - ''' - Contains parameters controlling the sampling. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_sampling')) - - -class settings_scf(MCategory): - ''' - Contains parameters connected with the convergence of the self-consistent field (SCF) - iterations. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_scf')) - - -class settings_smearing(MCategory): - ''' - Contain parameters that control the smearing of the orbital occupation at finite - electronic temperatures. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_smearing')) - - -class settings_stress_tensor(MCategory): - ''' - Settings to calculate the stress tensor (stress_tensor) consistent with the total - energy of the system given in energy_total. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='settings_stress_tensor')) - - -class stress_tensor_type(MCategory): - ''' - Contains the final value of the default stress tensor (stress_tensor) and/or the value - of the stress tensor (stress_tensor_value) of the kind defined in stress_tensor_kind. - ''' - - m_def = Category( - a_legacy=LegacyDefinition(name='stress_tensor_type')) - - -class energy_component_per_atom(MCategory): - ''' - A value of an energy component per atom, concurring in defining the total energy per - atom. - ''' - - m_def = Category( - categories=[energy_value], - a_legacy=LegacyDefinition(name='energy_component_per_atom')) - - -class energy_component(MCategory): - ''' - A value of an energy component, expected to be an extensive property. - ''' - - m_def = Category( - categories=[energy_value], - a_legacy=LegacyDefinition(name='energy_component')) - - -class energy_type_reference(MCategory): - ''' - This metadata stores an energy used as reference point. - ''' - - m_def = Category( - categories=[energy_value], - a_legacy=LegacyDefinition(name='energy_type_reference')) - - -class error_estimate(MCategory): - ''' - An estimate of the error on the converged (final) value. - ''' - - m_def = Category( - categories=[error_estimate_contribution], - a_legacy=LegacyDefinition(name='error_estimate')) - - -class message_info(MCategory): - ''' - An information message of the computational program. - ''' - - m_def = Category( - categories=[message_debug], - a_legacy=LegacyDefinition(name='message_info')) - - -class parallelization_info(MCategory): - ''' - Contains information on the parallelization of the program, i.e. which parallel - programming language was used and its version, how many cores had been working on the - calculation and the flags and parameters needed to run the parallelization of the - code. - ''' - - m_def = Category( - categories=[accessory_info], - a_legacy=LegacyDefinition(name='parallelization_info')) - - -class parsing_message_info(MCategory): - ''' - This field is used for info messages of the parsing program. - ''' - - m_def = Category( - categories=[parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_info')) - - -class program_info(MCategory): - ''' - Contains information on the program that generated the data, i.e. the program_name, - program_version, program_compilation_host and program_compilation_datetime as direct - children of this field. - ''' - - m_def = Category( - categories=[accessory_info], - a_legacy=LegacyDefinition(name='program_info')) - - -class settings_geometry_optimization(MCategory): - ''' - Contains parameters controlling the geometry optimization. - ''' - - m_def = Category( - categories=[settings_sampling], - a_legacy=LegacyDefinition(name='settings_geometry_optimization')) - - -class settings_k_points(MCategory): - ''' - Contains parameters that control the $k$-point mesh. - ''' - - m_def = Category( - categories=[settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_k_points')) - - -class settings_metadynamics(MCategory): - ''' - Contains parameters that control the metadynamics sampling. - ''' - - m_def = Category( - categories=[settings_sampling], - a_legacy=LegacyDefinition(name='settings_metadynamics')) - - -class settings_molecular_dynamics(MCategory): - ''' - Contains parameters that control the molecular dynamics sampling. - ''' - - m_def = Category( - categories=[settings_sampling], - a_legacy=LegacyDefinition(name='settings_molecular_dynamics')) - - -class settings_Monte_Carlo(MCategory): - ''' - Contains parameters that control the Monte-Carlo sampling. - ''' - - m_def = Category( - categories=[settings_sampling], - a_legacy=LegacyDefinition(name='settings_Monte_Carlo')) - - -class settings_XC(MCategory): - ''' - Contains parameters connected with the definition of the exchange-correlation (XC) - *method*. Here, the term *method* is a more general concept than just *functionals* - and include, e.g., post Hartree-Fock methods, too. - ''' - - m_def = Category( - categories=[settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_XC')) - - -class time_info(MCategory): - ''' - Stores information on the date and timings of the calculation. They are useful for, - e.g., debugging or visualization purposes. - ''' - - m_def = Category( - categories=[accessory_info], - a_legacy=LegacyDefinition(name='time_info')) - - -class energy_total_potential_per_atom(MCategory): - ''' - A value of the total potential energy per atom. Note that a direct comparison may not - be possible because of a difference in the methods for computing total energies and - numerical implementations of various codes might leads to different energy zeros (see - section_energy_code_independent for a code-independent definition of the energy). - ''' - - m_def = Category( - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_total_potential_per_atom')) - - -class energy_total_potential(MCategory): - ''' - A value of the total potential energy. Note that a direct comparison may not be - possible because of a difference in the methods for computing total energies and - numerical implementations of various codes might leads to different energy zeros (see - section_energy_code_independent for a code-independent definition of the energy). - ''' - - m_def = Category( - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_total_potential')) - - -class energy_type_C(MCategory): - ''' - This metadata stores the correlation (C) energy. - ''' - - m_def = Category( - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_type_C')) - - -class energy_type_van_der_Waals(MCategory): - ''' - This metadata stores the converged van der Waals energy. - ''' - - m_def = Category( - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_type_van_der_Waals')) - - -class energy_type_XC(MCategory): - ''' - This metadata stores the exchange-correlation (XC) energy. - ''' - - m_def = Category( - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_type_XC')) - - -class energy_type_X(MCategory): - ''' - This metadata stores the exchange (X) energy. - ''' - - m_def = Category( - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_type_X')) - - -class message_warning(MCategory): - ''' - A warning message of the computational program. - ''' - - m_def = Category( - categories=[message_info, message_debug], - a_legacy=LegacyDefinition(name='message_warning')) - - -class parsing_message_warning(MCategory): - ''' - This field is used for warning messages of the parsing program. - ''' - - m_def = Category( - categories=[parsing_message_info, parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_warning')) - - -class settings_barostat(MCategory): - ''' - Contains parameters controlling the barostat in a molecular dynamics calculation. - ''' - - m_def = Category( - categories=[settings_sampling, settings_molecular_dynamics], - a_legacy=LegacyDefinition(name='settings_barostat')) - - -class settings_integrator(MCategory): - ''' - Contains parameters that control the molecular dynamics (MD) integrator. - ''' - - m_def = Category( - categories=[settings_sampling, settings_molecular_dynamics], - a_legacy=LegacyDefinition(name='settings_integrator')) - - -class settings_post_hartree_fock(MCategory): - ''' - Contains parameters for the post Hartree-Fock method. - ''' - - m_def = Category( - categories=[settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_post_hartree_fock')) - - -class settings_relativity(MCategory): - ''' - Contains parameters and information connected with the relativistic treatment used in - the calculation. - ''' - - m_def = Category( - categories=[settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_relativity')) - - -class settings_self_interaction_correction(MCategory): - ''' - Contains parameters and information connected with the self-interaction correction - (SIC) method being used in self_interaction_correction_method. - ''' - - m_def = Category( - categories=[settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_self_interaction_correction')) - - -class settings_thermostat(MCategory): - ''' - Contains parameters that control the thermostat in the molecular dynamics (MD) - calculations. - ''' - - m_def = Category( - categories=[settings_sampling, settings_molecular_dynamics], - a_legacy=LegacyDefinition(name='settings_thermostat')) - - -class settings_van_der_Waals(MCategory): - ''' - Contain parameters and information connected with the Van der Waals treatment used in - the calculation to compute the Van der Waals energy (energy_van_der_Waals). - ''' - - m_def = Category( - categories=[settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_van_der_Waals')) - - -class settings_XC_functional(MCategory): - ''' - Contain parameters connected with the definition of the exchange-correlation (XC) - functional (see section_XC_functionals and XC_functional). - ''' - - m_def = Category( - categories=[settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_XC_functional')) - - -class message_error(MCategory): - ''' - An error message of the computational program. - ''' - - m_def = Category( - categories=[message_info, message_debug, message_warning], - a_legacy=LegacyDefinition(name='message_error')) - - -class parsing_message_error(MCategory): - ''' - This field is used for error messages of the parsing program. - ''' - - m_def = Category( - categories=[parsing_message_info, parsing_message_warning, parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_error')) - - -class settings_coupled_cluster(MCategory): - ''' - Contains parameters for the coupled-cluster method (CC) in the post Hartree-Fock step. - ''' - - m_def = Category( - categories=[settings_post_hartree_fock, settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_coupled_cluster')) - - -class settings_GW(MCategory): - ''' - Contains parameters for the GW-method in the post Hartree-Fock step, that expands the - self-energy in terms of the single particle Green's function $G$ and the screened - Coulomb interaction $W$. - ''' - - m_def = Category( - categories=[settings_post_hartree_fock, settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_GW')) - - -class settings_MCSCF(MCategory): - ''' - Contains parameters for the multi-configurational self-consistent-field (MCSCF) - method. - ''' - - m_def = Category( - categories=[settings_post_hartree_fock, settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_MCSCF')) - - -class settings_moller_plesset_perturbation_theory(MCategory): - ''' - Contains parameters for Møller–Plesset perturbation theory. - ''' - - m_def = Category( - categories=[settings_post_hartree_fock, settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_moller_plesset_perturbation_theory')) - - -class settings_multi_reference(MCategory): - ''' - Contains parameters for the multi-reference single and double configuration - interaction method. - ''' - - m_def = Category( - categories=[settings_post_hartree_fock, settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='settings_multi_reference')) - - -class archive_context(MSection): - ''' - Contains information relating to an archive. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='archive_context')) - - archive_gid = Quantity( - type=str, - shape=[], - description=''' - unique identifier of an archive. - ''', - a_legacy=LegacyDefinition(name='archive_gid')) - - -class calculation_context(MSection): - ''' - Contains information relating to a calculation. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='calculation_context')) - - calculation_gid = Quantity( - type=str, - shape=[], - description=''' - unique identifier of a calculation. - ''', - a_legacy=LegacyDefinition(name='calculation_gid')) - - -class section_atom_projected_dos(MSection): - ''' - Section collecting the information on an atom projected density of states (DOS) - evaluation. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_atom_projected_dos')) - - atom_projected_dos_energies = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atom_projected_dos_values'], - unit='joule', - description=''' - Array containing the set of discrete energy values for the atom-projected density - (electronic-energy) of states (DOS). - ''', - a_legacy=LegacyDefinition(name='atom_projected_dos_energies')) - - atom_projected_dos_lm = Quantity( - type=np.dtype(np.int32), - shape=['number_of_lm_atom_projected_dos', 2], - description=''' - Tuples of $l$ and $m$ values for which atom_projected_dos_values_lm are given. For - the quantum number $l$ the conventional meaning of azimuthal quantum number is - always adopted. For the integer number $m$, besides the conventional use as - magnetic quantum number ($l+1$ integer values from $-l$ to $l$), a set of - different conventions is accepted (see the [m_kind wiki - page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). - The adopted convention is specified by atom_projected_dos_m_kind. - ''', - a_legacy=LegacyDefinition(name='atom_projected_dos_lm')) - - atom_projected_dos_m_kind = Quantity( - type=str, - shape=[], - description=''' - String describing what the integer numbers of $m$ in atom_projected_dos_lm mean. - The allowed values are listed in the [m_kind wiki - page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). - ''', - a_legacy=LegacyDefinition(name='atom_projected_dos_m_kind')) - - atom_projected_dos_values_lm = Quantity( - type=np.dtype(np.float64), - shape=['number_of_lm_atom_projected_dos', 'number_of_spin_channels', 'number_of_atoms', 'number_of_atom_projected_dos_values'], - description=''' - Values correspond to the number of states for a given energy (the set of discrete - energy values is given in atom_projected_dos_energies) divided into contributions - from each $l,m$ channel for the atom-projected density (electronic-energy) of - states. Here, there are as many atom-projected DOS as the number_of_atoms, the - list of labels of the atoms and their meanings are in atom_labels. - ''', - a_legacy=LegacyDefinition(name='atom_projected_dos_values_lm')) - - atom_projected_dos_values_total = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_atoms', 'number_of_atom_projected_dos_values'], - description=''' - Values correspond to the number of states for a given energy (the set of discrete - energy values is given in atom_projected_dos_energies) divided into contributions - summed up over all $l$ channels for the atom-projected density (electronic-energy) - of states (DOS). Here, there are as many atom-projected DOS as the - number_of_atoms, the list of labels of the atoms and their meanings are in - atom_labels. - ''', - a_legacy=LegacyDefinition(name='atom_projected_dos_values_total')) - - number_of_atom_projected_dos_values = Quantity( - type=int, - shape=[], - description=''' - Gives the number of energy values for the atom-projected density of states (DOS) - based on atom_projected_dos_values_lm and atom_projected_dos_values_total. - ''', - a_legacy=LegacyDefinition(name='number_of_atom_projected_dos_values')) - - number_of_lm_atom_projected_dos = Quantity( - type=int, - shape=[], - description=''' - Gives the number of $l$, $m$ combinations for the atom projected density of states - (DOS) defined in section_atom_projected_dos. - ''', - a_legacy=LegacyDefinition(name='number_of_lm_atom_projected_dos')) - - -class section_atomic_multipoles(MSection): - ''' - Section describing multipoles (charges/monopoles, dipoles, quadrupoles, ...) for each - atom. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_atomic_multipoles')) - - atomic_multipole_kind = Quantity( - type=str, - shape=[], - description=''' - String describing the method used to obtain the electrostatic multipoles - (including the electric charge, dipole, etc.) for each atom. Such multipoles - require a charge-density partitioning scheme, specified by the value of this - metadata. Allowed values are listed in the [atomic_multipole_kind wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/atomic- - multipole-kind). - ''', - a_legacy=LegacyDefinition(name='atomic_multipole_kind')) - - atomic_multipole_lm = Quantity( - type=np.dtype(np.int32), - shape=['number_of_lm_atomic_multipoles', 2], - description=''' - Tuples of $l$ and $m$ values for which the atomic multipoles (including the - electric charge, dipole, etc.) are given. The method used to obtain the multipoles - is specified by atomic_multipole_kind. The meaning of the integer number $l$ is - monopole/charge for $l=0$, dipole for $l=1$, quadrupole for $l=2$, etc. The - meaning of the integer numbers $m$ is specified by atomic_multipole_m_kind. - ''', - a_legacy=LegacyDefinition(name='atomic_multipole_lm')) - - atomic_multipole_m_kind = Quantity( - type=str, - shape=[], - description=''' - String describing the definition for each integer number $m$ in - atomic_multipole_lm. Allowed values are listed in the [m_kind wiki - page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). - ''', - a_legacy=LegacyDefinition(name='atomic_multipole_m_kind')) - - atomic_multipole_values = Quantity( - type=np.dtype(np.float64), - shape=['number_of_lm_atomic_multipoles', 'number_of_atoms'], - description=''' - Value of the multipoles (including the monopole/charge for $l$ = 0, the dipole for - $l$ = 1, etc.) for each atom, calculated as described in atomic_multipole_kind. - ''', - a_legacy=LegacyDefinition(name='atomic_multipole_values')) - - number_of_lm_atomic_multipoles = Quantity( - type=int, - shape=[], - description=''' - Gives the number of $l$, $m$ combinations for atomic multipoles - atomic_multipole_lm. - ''', - a_legacy=LegacyDefinition(name='number_of_lm_atomic_multipoles')) - - -class section_basis_functions_atom_centered(MSection): - ''' - This section contains the description of the basis functions (at least one function) - of the (atom-centered) basis set defined in section_basis_set_atom_centered. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_basis_functions_atom_centered')) - - -class section_basis_set_atom_centered(MSection): - ''' - This section describes the atom-centered basis set. The main contained information is - a short, non unique but human-interpretable, name for identifying the basis set - (basis_set_atom_centered_short_name), a longer, unique name - (basis_set_atom_centered_unique_name), the atomic number of the atomic species the - basis set is meant for (basis_set_atom_number), and a list of actual basis functions - in the section_basis_functions_atom_centered section. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_basis_set_atom_centered')) - - basis_set_atom_centered_ls = Quantity( - type=np.dtype(np.int32), - shape=['number_of_kinds_in_basis_set_atom_centered'], - description=''' - Azimuthal quantum number ($l$) values (of the angular part given by the spherical - harmonic $Y_{lm}$) of the atom-centered basis function defined in the current - section_basis_set_atom_centered. - ''', - a_legacy=LegacyDefinition(name='basis_set_atom_centered_ls')) - - basis_set_atom_centered_radial_functions = Quantity( - type=np.dtype(np.float64), - shape=['number_of_kinds_in_basis_set_atom_centered', 401, 5], - description=''' - Values of the radial function of the different basis function kinds. The values - are numerically tabulated on a default 0.01-nm equally spaced grid from 0 to 4 nm. - The 5 tabulated values are $r$, $f(r)$, $f'(r)$, $f(r) \\cdot r$, - $\\frac{d}{dr}(f(r) \\cdot r)$. - ''', - a_legacy=LegacyDefinition(name='basis_set_atom_centered_radial_functions')) - - basis_set_atom_centered_short_name = Quantity( - type=str, - shape=[], - description=''' - Code-specific, but explicative, base name for the basis set (not unique). Details - are explained in the [basis_set_atom_centered_short_name wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- - set-atom-centered-short-name), this name should not contain the *atom kind* (to - simplify the use of a single name for multiple elements). - ''', - a_legacy=LegacyDefinition(name='basis_set_atom_centered_short_name')) - - basis_set_atom_centered_unique_name = Quantity( - type=str, - shape=[], - description=''' - Code-specific, but explicative, base name for the basis set (not unique). This - string starts with basis_set_atom_centered_short_name. If the basis set defined in - this section_basis_set_atom_centered is not identical to the default definition - (stored in a database) of the basis set with the same name stored in a database, - then the string is extended by 10 identifiable characters as explained in the - [basis_set_atom_centered_name wiki page](https://gitlab.mpcdf.mpg.de/nomad- - lab/nomad-meta-info/wikis/metainfo/basis-set-atom-centered-unique-name). The - reason for this procedure is that often atom-centered basis sets are obtained by - fine tuning basis sets provided by the code developers or other sources. Each - basis sets, which has normally a standard name, often reported in publications, - has also several parameters that can be tuned. This metadata tries to keep track - of the original basis set and its modifications. This string here defined should - not contain the *atom kind* for which this basis set is intended for, in order to - simplify the use of a single name for multiple *atom kinds* (see atom_labels for - the actual meaning of *atom kind*). - ''', - a_legacy=LegacyDefinition(name='basis_set_atom_centered_unique_name')) - - basis_set_atom_number = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - Atomic number (i.e., number of protons) of the atom for which this basis set is - constructed (0 means unspecified or a pseudo atom). - ''', - a_legacy=LegacyDefinition(name='basis_set_atom_number')) - - number_of_basis_functions_in_basis_set_atom_centered = Quantity( - type=int, - shape=[], - description=''' - Gives the number of different basis functions in a section_basis_set_atom_centered - section. This equals the number of actual coefficients that are specified when - using this basis set. - ''', - a_legacy=LegacyDefinition(name='number_of_basis_functions_in_basis_set_atom_centered')) - - number_of_kinds_in_basis_set_atom_centered = Quantity( - type=int, - shape=[], - description=''' - Gives the number of different *kinds* of radial basis functions in the - section_basis_set_atom_centered section. Specifically, basis functions with the - same $n$ and $l$ quantum numbers are grouped in sets. Each set counts as one - *kind*. - ''', - a_legacy=LegacyDefinition(name='number_of_kinds_in_basis_set_atom_centered')) - - section_basis_functions_atom_centered = SubSection( - sub_section=SectionProxy('section_basis_functions_atom_centered'), - repeats=True, - a_legacy=LegacyDefinition(name='section_basis_functions_atom_centered')) - - section_gaussian_basis_group = SubSection( - sub_section=SectionProxy('section_gaussian_basis_group'), - repeats=True, - a_legacy=LegacyDefinition(name='section_gaussian_basis_group')) - - -class section_basis_set_cell_dependent(MSection): - ''' - Section describing a cell-dependent (atom-independent) basis set, e.g. plane waves. - The contained information is the type of basis set (in basis_set_cell_dependent_kind), - its parameters (e.g., for plane waves in basis_set_planewave_cutoff), and a name that - identifies the actually used basis set (a string combining the type and the - parameter(s), stored in basis_set_cell_dependent_name). - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_basis_set_cell_dependent')) - - basis_set_cell_dependent_kind = Quantity( - type=str, - shape=[], - description=''' - A string defining the type of the cell-dependent basis set (i.e., non atom - centered such as plane-waves). Allowed values are listed in the - [basis_set_cell_dependent_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad- - lab/nomad-meta-info/wikis/metainfo/basis-set-cell-dependent-kind). - ''', - a_legacy=LegacyDefinition(name='basis_set_cell_dependent_kind')) - - basis_set_cell_dependent_name = Quantity( - type=str, - shape=[], - description=''' - A label identifying the cell-dependent basis set (i.e., non atom centered such as - plane-waves). Allowed values are listed in the [basis_set_cell_dependent_name wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- - set-cell-dependent-name). - ''', - a_legacy=LegacyDefinition(name='basis_set_cell_dependent_name')) - - basis_set_planewave_cutoff = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Spherical cutoff in reciprocal space for a plane-wave basis set. It is the energy - of the highest plan-ewave ($\\frac{\\hbar^2|k+G|^2}{2m_e}$) included in the basis - set. Note that normally this basis set is used for the wavefunctions, and the - density would have 4 times the cutoff, but this actually depends on the use of the - basis set by the method. - ''', - a_legacy=LegacyDefinition(name='basis_set_planewave_cutoff')) - - -class section_basis_set(MSection): - ''' - This section contains references to *all* basis sets used in this - section_single_configuration_calculation. More than one basis set instance per *single - configuration calculation* (see section_single_configuration_calculation) may be - needed. This is true for example, for codes that implement adaptive basis sets along - the self-consistent field (SCF) convergence (e.g., exciting). In such cases, there is - a section_basis_set instance per SCF iteration, if necessary. Another example is - having a basis set for wavefunctions, a different one for the density, an auxiliary - basis set for resolution of identity (RI), etc. - - Supported are the two broad classes of basis sets: *atom-centered* (e.g., Gaussian- - type, numerical atomic orbitals) and *cell-dependent* (like plane waves or real-space - grids, so named because they are typically used for periodic-system calculations and - dependent to the simulated cell as a whole). - - Basis sets used in this section_single_configuration_calculation, belonging to either - class, are defined in the dedicated section: [section_basis_set_cell_dependent - ](section_basis_set_cell_dependent) or section_basis_set_atom_centered. The - correspondence between the basis sets listed in this section and the definition given - in the dedicated sessions is given by the two concrete metadata: - mapping_section_basis_set_cell_dependent and mapping_section_basis_set_atom_centered. - The latter metadata is a list that connects each atom in the system with its basis - set, where the same basis set can be assigned to more than one atom. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_basis_set')) - - basis_set_kind = Quantity( - type=str, - shape=[], - description=''' - String describing the use of the basis set, i.e, if it used for expanding a wave- - function or an electron density. Allowed values are listed in the [basis_set_kind - wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/basis-set-kind). - ''', - a_legacy=LegacyDefinition(name='basis_set_kind')) - - basis_set_name = Quantity( - type=str, - shape=[], - description=''' - String identifying the basis set in an unique way. The rules for building this - string are specified in the [basis_set_name wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- - set-name). - ''', - a_legacy=LegacyDefinition(name='basis_set_name')) - - mapping_section_basis_set_atom_centered = Quantity( - type=Reference(SectionProxy('section_basis_set_atom_centered')), - shape=['number_of_atoms'], - description=''' - An array of the dimension of number_of_atoms where each atom (identified by the - index in the array) is assigned to an atom-centered basis set, for this - section_single_configuration_calculation. The actual definition of the atom- - centered basis set is in the section_basis_set_atom_centered that is referred to - by this metadata. - ''', - a_legacy=LegacyDefinition(name='mapping_section_basis_set_atom_centered')) - - mapping_section_basis_set_cell_dependent = Quantity( - type=Reference(SectionProxy('section_basis_set_cell_dependent')), - shape=[], - description=''' - Assignment of the cell-dependent (i.e., non atom centered, e.g., plane-waves) - parts of the basis set, which is defined (type, parameters) in - section_basis_set_cell_dependent that is referred to by this metadata. - ''', - a_legacy=LegacyDefinition(name='mapping_section_basis_set_cell_dependent')) - - number_of_basis_functions = Quantity( - type=int, - shape=[], - description=''' - Stores the total number of basis functions in a section_basis_set section. - ''', - a_legacy=LegacyDefinition(name='number_of_basis_functions')) - - -class section_restricted_uri(MSection): - ''' - Restricted URIs on this calculation (Coverage: any info or files that are related with - this calculation can be subject to restriction) - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_restricted_uri')) - - number_of_restricted_uri = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - The number of restricted uris in restricted_uri list. - ''', - a_legacy=LegacyDefinition(name='number_of_restricted_uri')) - - restricted_uri = Quantity( - type=str, - shape=['number_of_restricted_uri'], - description=''' - The list of nomad uri(s) identifying the restricted info/file corresponding to - this calculation - ''', - a_legacy=LegacyDefinition(name='restricted_uri')) - - restricted_uri_reason = Quantity( - type=str, - shape=[], - description=''' - The reason of restriction for the uri or file. The reason can be 'propriety - license', 'open-source redistribution restricted license', 'other license', or - 'author restricted'. - ''', - a_legacy=LegacyDefinition(name='restricted_uri_reason')) - - restricted_uri_issue_authority = Quantity( - type=str, - shape=[], - description=''' - The issue authority is the restriction owner for the uri or file. This can be - license owner such as 'VASP' or 'AMBER', 'NOMAD', or the author of the uri. For - example the repository user name of the author. - ''', - a_legacy=LegacyDefinition(name='restricted_uri_issue_authority')) - - restricted_uri_end_date = Quantity( - type=str, - shape=[], - description=''' - The deadline date of the restriction for the uri or file. The end date can be in - date format string for those restrictions set by authors or NOMAD otherwise it is - set to 'unlimited' for the restriction related to license. - ''', - a_legacy=LegacyDefinition(name='restricted_uri_end_date')) - - restricted_uri_restriction = Quantity( - type=str, - shape=[], - description=''' - The type of restriction for the uri or file. The type can be 'any access' or - 'license permitted'. - ''', - a_legacy=LegacyDefinition(name='restricted_uri_restriction')) - - restricted_uri_license = Quantity( - type=str, - shape=[], - description=''' - The info of the license that is the reason of restriction. - ''', - a_legacy=LegacyDefinition(name='restricted_uri_license')) - - number_of_restricted_uri_files = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - The number of restricted files in restricted_uri_files list. - ''', - a_legacy=LegacyDefinition(name='number_of_restricted_uri_files')) - - -class section_calculation_to_calculation_refs(MSection): - ''' - Section that describes the relationship between different - section_single_configuration_calculation sections. - - For instance, one calculation is a perturbation performed using a self-consistent - field (SCF) calculation as starting point, or a simulated system is partitioned in - regions with different but connected Hamiltonians (e.g., QM/MM, or a region treated - via Kohn-Sham DFT embedded into a region treated via orbital-free DFT). - - The kind of relationship between the calculation defined in this section and the - referenced one is described by calculation_to_calculation_kind. The referenced - section_single_configuration_calculation is identified via - calculation_to_calculation_ref (typically used for a - section_single_configuration_calculation in the same section_run) or - calculation_to_calculation_external_url. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_calculation_to_calculation_refs')) - - calculation_to_calculation_external_url = Quantity( - type=str, - shape=[], - description=''' - URL used to reference an externally stored calculation. The kind of relationship - between the present and the referenced section_single_configuration_calculation is - specified by calculation_to_calculation_kind. - ''', - a_legacy=LegacyDefinition(name='calculation_to_calculation_external_url')) - - calculation_to_calculation_kind = Quantity( - type=str, - shape=[], - description=''' - String defining the relationship between the referenced - section_single_configuration_calculation and the present - section_single_configuration_calculation. Valid values are described in the - [calculation_to_calculation_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad- - lab/nomad-meta-info/wikis/metainfo/calculation-to-calculation-kind). Often - calculations are connected, for instance, one calculation is a perturbation - performed using a self-consistent field (SCF) calculation as starting point, or a - simulated system is partitioned in regions with different but connected - Hamiltonians (e.g., QM/MM, or a region treated via Kohn-Sham DFT embedded into a - region treated via orbital-free DFT). Hence, the need of keeping track of these - connected calculations. The referenced calculation is identified via - calculation_to_calculation_ref (typically used for a calculation in the same - section_run) or calculation_to_calculation_external_url. - ''', - a_legacy=LegacyDefinition(name='calculation_to_calculation_kind')) - - calculation_to_calculation_ref = Quantity( - type=Reference(SectionProxy('section_single_configuration_calculation')), - shape=[], - description=''' - Reference to another calculation. If both this and - calculation_to_calculation_external_url are given, then - calculation_to_calculation_ref is a local copy of the URL given in - calculation_to_calculation_external_url. The kind of relationship between the - present and the referenced section_single_configuration_calculation is specified - by calculation_to_calculation_kind. - ''', - a_legacy=LegacyDefinition(name='calculation_to_calculation_ref')) - - -class section_calculation_to_folder_refs(MSection): - ''' - Section that describes the relationship between - section_single_configuration_calculationa and the folder containing the original - calulations - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_calculation_to_folder_refs')) - - calculation_to_folder_external_url = Quantity( - type=str, - shape=[], - description=''' - URL used to reference a folder containing external calculations. The kind of - relationship between the present and the referenced - section_single_configuration_calculation is specified by - calculation_to_folder_kind. - ''', - a_legacy=LegacyDefinition(name='calculation_to_folder_external_url')) - - calculation_to_folder_kind = Quantity( - type=str, - shape=[], - description=''' - String defining the relationship between the referenced - section_single_configuration_calculation and a folder containing calculations. - ''', - a_legacy=LegacyDefinition(name='calculation_to_folder_kind')) - - -class section_dos_fingerprint(MSection): - ''' - Section for the fingerprint of the electronic density-of-states (DOS). - DOS fingerprints are a modification of the D-Fingerprints reported in Chem. Mater. 2015, 27, 3, 735–743 - (doi:10.1021/cm503507h). The fingerprint consists of a binary representation of the DOS, - that is used to evaluate the similarity of materials based on their electronic structure. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_dos_fingerprint')) - - bins = Quantity( - type=str, - description=''' - Byte representation of the DOS fingerprint. - ''', - a_legacy=LegacyDefinition(name='bins')) - - indices = Quantity( - type=np.dtype(np.int16), - shape=[2], - description=''' - Indices used to compare DOS fingerprints of different energy ranges. - ''', - a_legacy=LegacyDefinition(name='indices')) - - stepsize = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Stepsize of interpolation in the first step of the generation of DOS fingerprints. - ''', - a_legacy=LegacyDefinition(name='stepsize')) - - filling_factor = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Proportion of 1 bins in the DOS fingerprint. - ''', - a_legacy=LegacyDefinition(name='filling_factor')) - - grid_id = Quantity( - type=str, - description=''' - Identifier of the DOS grid that was used for the creation of the fingerprint. - Similarity can only be calculated if the same grid was used for both fingerprints. - ''', - a_legacy=LegacyDefinition(name='grid_id')) - - -class section_dos(MSection): - ''' - Section collecting information of a (electronic-energy or vibrational-energy) density - of states (DOS) evaluation. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_dos')) - - dos_energies_normalized = Quantity( - type=np.dtype(np.float64), - shape=['number_of_dos_values'], - unit='joule', - description=''' - Array containing the set of discrete energy values with respect to the - highest occupied energy level. This is the total DOS, see - atom_projected_dos_energies and species_projected_dos_energies for - partial density of states. - - If not available through energy_reference_highest_occupied, the highest - occupied energy level is detected by searching for a non-zero DOS value - below (or nearby) the reported energy_reference_fermi. In case the - highest occupied energy level cannot be detected accurately, the - normalized values are not reported. For calculations with multiple - spin-channels, the normalization is determined by the first channel. - ''', - a_legacy=LegacyDefinition(name='dos_energies_normalized')) - - dos_energies = Quantity( - type=np.dtype(np.float64), - shape=['number_of_dos_values'], - unit='joule', - description=''' - Array containing the set of discrete energy values for the density (electronic- - energy or vibrational energy) of states (DOS). This is the total DOS, see - atom_projected_dos_energies and species_projected_dos_energies for partial density - of states. - ''', - a_legacy=LegacyDefinition(name='dos_energies')) - - dos_integrated_values = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_dos_values'], - description=''' - Integrated density of states (starting at $-\\infty$), pseudo potential - calculations should start with the number of core electrons if they cover only the - active electrons - ''', - a_legacy=LegacyDefinition(name='dos_integrated_values')) - - dos_kind = Quantity( - type=str, - shape=[], - description=''' - String to specify the kind of density of states (either electronic or - vibrational). - ''', - a_legacy=LegacyDefinition(name='dos_kind')) - - dos_lm = Quantity( - type=np.dtype(np.int32), - shape=['number_of_dos_lms', 2], - description=''' - Tuples of $l$ and $m$ values for which dos_values_lm are given. For the quantum - number $l$ the conventional meaning of azimuthal quantum number is always adopted. - For the integer number $m$, besides the conventional use as magnetic quantum - number ($l+1$ integer values from $-l$ to $l$), a set of different conventions is - accepted (see the [m_kind wiki page](https://gitlab.rzg.mpg.de/nomad-lab/nomad- - meta-info/wikis/metainfo/m-kind). The actual adopted convention is specified by - dos_m_kind. - ''', - a_legacy=LegacyDefinition(name='dos_lm')) - - dos_m_kind = Quantity( - type=str, - shape=[], - description=''' - String describing what the integer numbers of $m$ in dos_lm mean. The allowed - values are listed in the [m_kind wiki page](https://gitlab.rzg.mpg.de/nomad- - lab/nomad-meta-info/wikis/metainfo/m-kind). - ''', - a_legacy=LegacyDefinition(name='dos_m_kind')) - - dos_values_lm = Quantity( - type=np.dtype(np.float64), - shape=['number_of_dos_lms', 'number_of_spin_channels', 'number_of_atoms', 'number_of_dos_values'], - unit='joule', - description=''' - Array containing the density (electronic-energy) of states values projected on the - various spherical harmonics (integrated on all atoms), see - atom_projected_dos_values_lm for atom values. - ''', - a_legacy=LegacyDefinition(name='dos_values_lm')) - - dos_values_normalized = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_dos_values'], - description=''' - Density of states (DOS) values divided by the unit cell volume and by the number - of atoms. - ''', - a_legacy=LegacyDefinition(name='dos_values_normalized')) - - dos_values = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_dos_values'], - description=''' - Values (number of states for a given energy, the set of discrete energy values is - given in dos_energies) of density (electronic-energy or vibrational-energy) of - states. This refers to the simulation cell, i.e. integrating over all energies - will give the number of electrons in the simulation cell. - ''', - a_legacy=LegacyDefinition(name='dos_values')) - - number_of_dos_lms = Quantity( - type=int, - shape=[], - description=''' - Gives the number of $l$, $m$ combinations for the given projected density of - states (DOS) in dos_values and dos_values_lm. - ''', - a_legacy=LegacyDefinition(name='number_of_dos_lms')) - - number_of_dos_values = Quantity( - type=int, - shape=[], - description=''' - Gives the number of energy values for the density of states (DOS), see - dos_energies. - ''', - a_legacy=LegacyDefinition(name='number_of_dos_values')) - - section_dos_fingerprint = SubSection( - sub_section=SectionProxy('section_dos_fingerprint'), - repeats=False, - a_legacy=LegacyDefinition(name='section_dos_fingerprint')) - - -class section_eigenvalues(MSection): - ''' - Section containing (electronic-energy) eigenvalues for one spin channel. If, for - example, the eigenvalues of the Kohn-Sham operator are to be stored, a string - identifying this kind of eigenvalues is put in eigenvalues_kind, the coordinates of - the $k$-points at which the eigenvalues are evaluated is stored in - eigenvalues_kpoints, and the energy values of the eigenstates and their occupation is - stored in eigenvalues_values and eigenvalues_occupation, respectively. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_eigenvalues')) - - eigenvalues_kind = Quantity( - type=str, - shape=[], - description=''' - A short string describing the kind of eigenvalues, as defined in the - [eigenvalues_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/eigenvalues-kind). - ''', - a_legacy=LegacyDefinition(name='eigenvalues_kind')) - - eigenvalues_kpoints_multiplicity = Quantity( - type=np.dtype(np.float64), - shape=['number_of_eigenvalues_kpoints'], - description=''' - Multiplicity of the $k$ point (i.e., how many distinct points per cell this - expands to after applying all symmetries). This defaults to 1. If expansion is - preformed then each point will have weight - eigenvalues_kpoints_weights/eigenvalues_kpoints_multiplicity. - ''', - a_legacy=LegacyDefinition(name='eigenvalues_kpoints_multiplicity')) - - eigenvalues_kpoints_weights = Quantity( - type=np.dtype(np.float64), - shape=['number_of_eigenvalues_kpoints'], - description=''' - Weights of the $k$ points (in the basis of the reciprocal lattice vectors) used - for the evaluation of the eigenvalues tabulated in eigenvalues_values, should - account for symmetry too. - ''', - a_legacy=LegacyDefinition(name='eigenvalues_kpoints_weights')) - - eigenvalues_kpoints = Quantity( - type=np.dtype(np.float64), - shape=['number_of_eigenvalues_kpoints', 3], - description=''' - Coordinates of the $k$ points (in the basis of the reciprocal lattice vectors) - used for the evaluation of the eigenvalues tabulated in eigenvalues_values. - ''', - a_legacy=LegacyDefinition(name='eigenvalues_kpoints')) - - eigenvalues_occupation = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], - description=''' - Occupation of the eigenstates. The corresponding eigenvalues (energy) are given in - eigenvalues_values. The coordinates in the reciprocal space are defined in - eigenvalues_kpoints. - ''', - a_legacy=LegacyDefinition(name='eigenvalues_occupation')) - - eigenvalues_values = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'], - unit='joule', - description=''' - Values of the (electronic-energy) eigenvalues. The coordinates of the - corresponding eigenstates in the reciprocal space are defined in - eigenvalues_kpoints and their occupations are given in eigenvalues_occupation. - ''', - a_legacy=LegacyDefinition(name='eigenvalues_values')) - - number_of_band_segment_eigenvalues = Quantity( - type=int, - shape=[], - description=''' - Gives the number of eigenvalues in a band segment, see band_energies. - ''', - a_legacy=LegacyDefinition(name='number_of_band_segment_eigenvalues')) - - number_of_eigenvalues_kpoints = Quantity( - type=int, - shape=[], - description=''' - Gives the number of $k$ points, see eigenvalues_kpoints. $k$ points are calculated - within a run and are irreducible if a symmetry is used. - ''', - a_legacy=LegacyDefinition(name='number_of_eigenvalues_kpoints')) - - number_of_eigenvalues = Quantity( - type=int, - shape=[], - description=''' - Gives the number of eigenvalues, see eigenvalues_values. - ''', - a_legacy=LegacyDefinition(name='number_of_eigenvalues')) - - number_of_normalized_band_segment_eigenvalues = Quantity( - type=int, - shape=[], - description=''' - Gives the number of normalized eigenvalues in a band segment, see - - band_energies_normalized. - ''', - a_legacy=LegacyDefinition(name='number_of_normalized_band_segment_eigenvalues')) - - -class section_energy_code_independent(MSection): - ''' - Section describing a code-independent total energy obtained by subtracting some - reference energy calculated with the same code. It contains the type in - energy_code_independent_kind and the computed code-independent total energy in - energy_code_independent_value. The computed energy allows for comparisons among - different codes and numerical settings. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_energy_code_independent')) - - energy_code_independent_kind = Quantity( - type=str, - shape=[], - description=''' - Type of the code-independent total energy (obtained by subtracting a reference - energy calculated with the same code), created to be comparable among different - codes and numerical settings. Details can be found on the [energy_code_independent - wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/energy-code-independent). - ''', - a_legacy=LegacyDefinition(name='energy_code_independent_kind')) - - energy_code_independent_value = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the code-independent total energy (obtained by subtracting a reference - energy calculated with the same code). This value is created to be comparable - among different codes and numerical settings. Details can be found on the - [energy_code_independent wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- - meta-info/wikis/metainfo/energy-code-independent). - ''', - categories=[energy_component, energy_value, energy_total_potential], - a_legacy=LegacyDefinition(name='energy_code_independent_value')) - - -class section_energy_van_der_Waals(MSection): - ''' - Section containing the Van der Waals energy value (energy_van_der_Waals_value) of type - van_der_Waals_kind. This is used when more than one Van der Waals methods are applied - in the same *single configuration calculation*, see - section_single_configuration_calculation. The main Van der Waals method (the one - concurring to energy_current, and used, e.g., for evaluating the forces for a - relaxation or dynamics) is given in energy_van_der_Waals and is defined in - settings_van_der_Waals. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_energy_van_der_Waals')) - - energy_van_der_Waals_kind = Quantity( - type=str, - shape=[], - description=''' - Method used to compute van der Waals energy stored in energy_van_der_Waals_value. - This metadata is used when more than one van der Waals method is applied in the - same *single configuration calculation* (see - section_single_configuration_calculation). The method used for van der Waals (the - one consistent with energy_current and, e.g., for evaluating the forces for a - relaxation or dynamics) is defined in settings_van_der_Waals. - ''', - a_legacy=LegacyDefinition(name='energy_van_der_Waals_kind')) - - energy_van_der_Waals_value = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of van der Waals energy, calculated with the method defined in - energy_van_der_Waals_kind. This metadata is used when more than one van der Waals - method is applied in the same *single configuration calculation* (see - section_single_configuration_calculation). The value of the van der Waals energy - consistent with energy_current and used, e.g., for evaluating the forces for a - relaxation or dynamics, is given in energy_van_der_Waals and defined in - settings_van_der_Waals. - ''', - categories=[energy_type_van_der_Waals, energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_van_der_Waals_value')) - - energy_van_der_Waals = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value for the converged van der Waals energy calculated using the method described - in van_der_Waals_method, and used in energy_current. This is the van der Waals - method consistent with, e.g., forces used for relaxation or dynamics. Alternative - methods are listed in section_energy_van_der_Waals. - ''', - categories=[energy_type_van_der_Waals, energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_van_der_Waals')) - - -class section_energy_contribution(MSection): - ''' - Section describing the contributions to the total energy. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_energy_contribution')) - - energy_contibution_kind = Quantity( - type=str, - shape=[], - description=''' - The kind of the energy contribution. Can be one of bond, pair, coulomb, etc. - ''', - a_legacy=LegacyDefinition(name='energy_contibution_kind')) - - energy_contribution_value = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the energy contribution. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_contribution_value')) - - -class section_frame_sequence_user_quantity(MSection): - ''' - Section collecting some user-defined quantities evaluated along a sequence of frame. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_frame_sequence_user_quantity')) - - frame_sequence_user_quantity_frames = Quantity( - type=np.dtype(np.int32), - shape=['number_of_user_quantity_evaluations_in_sequence'], - description=''' - Array containing the strictly increasing indices referring to the frames of - frame_sequence_user_quantity. If not given it defaults to the trivial mapping - 0,1,... - ''', - a_legacy=LegacyDefinition(name='frame_sequence_user_quantity_frames')) - - frame_sequence_user_quantity_name = Quantity( - type=str, - shape=[], - description=''' - Descriptive name of a user-defined quantity, sampled along this sequence of frames - (i.e., a trajectory, a frame is one section_single_configuration_calculation). - Dedicated metadata are created for the conserved energy-like quantity - (frame_sequence_conserved_quantity), the kinetic and potential energies - (frame_sequence_kinetic_energy and frame_sequence_potential_energy), the - instantaneous temperature (frame_sequence_temperature) and pressure - (frame_sequence_pressure). This metadata should be used for other quantities that - are monitored along a sequence of frames. - ''', - a_legacy=LegacyDefinition(name='frame_sequence_user_quantity_name')) - - frame_sequence_user_quantity_stats = Quantity( - type=np.dtype(np.float64), - shape=[2, 'number_of_frame_sequence_user_quantity_components'], - description=''' - Average of frame_sequence_user_quantity and its standard deviation in this - sequence of frames (i.e., a trajectory, a frame is one - section_single_configuration_calculation). - ''', - a_legacy=LegacyDefinition(name='frame_sequence_user_quantity_stats')) - - frame_sequence_user_quantity = Quantity( - type=np.dtype(np.float64), - shape=['number_of_user_quantity_evaluations_in_sequence', 'number_of_frame_sequence_user_quantity_components'], - description=''' - Array containing the values of the user-defined quantity defined in - frame_sequence_user_quantity_name, evaluated along this sequence of frames (i.e., - trajectory, a frame is one section_single_configuration_calculation). If not all - frames have a value the indices of the frames that have a value are stored in - frame_sequence_kinetic_energy_frames. If not all frames have a value the indices - of the frames that have a value are stored in - frame_sequence_kinetic_energy_frames. - ''', - a_legacy=LegacyDefinition(name='frame_sequence_user_quantity')) - - number_of_frame_sequence_user_quantity_components = Quantity( - type=int, - shape=[], - description=''' - Gives the number of user-defined quantity defined by - frame_sequence_user_quantity_name and monitored in a sequence of frames. A - sequence is a trajectory, which can have number_of_frames_in_sequence each - representing one section_single_configuration_calculation section. - - Dedicated metadata monitored along a sequence of frames are created for the - conserved energy-like quantity (frame_sequence_conserved_quantity), the kinetic - and potential energies ([frame_sequence_kinetic_energy and - frame_sequence_potential_energy](frame_sequence_kinetic_energy and - frame_sequence_potential_energy)), the instantaneous temperature - (frame_sequence_temperature) and the pressure (frame_sequence_pressure). - ''', - a_legacy=LegacyDefinition(name='number_of_frame_sequence_user_quantity_components')) - - number_of_user_quantity_evaluations_in_sequence = Quantity( - type=int, - shape=[], - description=''' - Gives the number of user defined quantity evaluations along a sequence of - frame_sequence_user_quantity frames. A sequence is a trajectory, which can have - number_of_frames_in_sequence each representing one - section_single_configuration_calculation section. - ''', - a_legacy=LegacyDefinition(name='number_of_user_quantity_evaluations_in_sequence')) - - -class section_frame_sequence(MSection): - ''' - Section containing a sequence of frames, i.e. a trajectory which can have - number_of_frames_in_sequence each representing one - section_single_configuration_calculation section evaluated with a sampling method - (e.g, molecular dynamics, Monte Carlo, geometry optimization). The sampling method - might be a subset of the whole trajectory. - - Information on the method used for the sampling can be found in the - section_sampling_method section and information of each frame of the sequence are - found in the section_single_configuration_calculation section. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_frame_sequence')) - - frame_sequence_conserved_quantity_frames = Quantity( - type=np.dtype(np.int32), - shape=['number_of_conserved_quantity_evaluations_in_sequence'], - description=''' - Array containing the strictly increasing indices of the frames the - frame_sequence_conserved_quantity values refers to. If not given it defaults to - the trivial mapping 0,1,... - ''', - a_legacy=LegacyDefinition(name='frame_sequence_conserved_quantity_frames')) - - frame_sequence_conserved_quantity_stats = Quantity( - type=np.dtype(np.float64), - shape=[2], - unit='joule', - description=''' - Average value of energy-like frame_sequence_conserved_quantity, and its standard - deviation, over this sequence of frames (i.e., a trajectory, a frame is one - section_single_configuration_calculation). - ''', - a_legacy=LegacyDefinition(name='frame_sequence_conserved_quantity_stats')) - - frame_sequence_conserved_quantity = Quantity( - type=np.dtype(np.float64), - shape=['number_of_conserved_quantity_evaluations_in_sequence'], - unit='joule', - description=''' - Array containing the values of a quantity that should be conserved, along a - sequence of frames (i.e., a trajectory). A frame is one - section_single_configuration_calculation), for example the total energy in the NVE - ensemble. If not all frames have a value the indices of the frames that have a - value are stored in frame_sequence_conserved_quantity_frames. - ''', - a_legacy=LegacyDefinition(name='frame_sequence_conserved_quantity')) - - frame_sequence_continuation_kind = Quantity( - type=Reference(SectionProxy('section_frame_sequence')), - shape=[], - description=''' - Type of continuation that has been performed from the previous sequence of frames - (i.e., a trajectory, a frame is one section_single_configuration_calculation), - upon restart. - ''', - a_legacy=LegacyDefinition(name='frame_sequence_continuation_kind')) - - frame_sequence_external_url = Quantity( - type=str, - shape=[], - description=''' - If the energy, forces, and other quantities for the frames (a frame is one - section_single_configuration_calculation) in section_frame_sequence are obtained - by calling a different code than the code that drives the sequence (e.g., a - wrapper that drives a molecular dynamics, Monte Carlo, geometry optimization and - calls an electronic-structure code for energy and forces for each configuration), - this metadata holds the reference to where the - section_single_configuration_calculation for each frame are located. The format - for this reference is described in the [frame_sequence_external_url wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/frame- - sequence-external-url). - ''', - a_legacy=LegacyDefinition(name='frame_sequence_external_url')) - - frame_sequence_kinetic_energy_frames = Quantity( - type=np.dtype(np.int32), - shape=['number_of_kinetic_energies_in_sequence'], - description=''' - Array containing the strictly increasing indices referring to the frames of - frame_sequence_kinetic_energy. If not given it defaults to the trivial mapping - 0,1,... - ''', - a_legacy=LegacyDefinition(name='frame_sequence_kinetic_energy_frames')) - - frame_sequence_kinetic_energy_stats = Quantity( - type=np.dtype(np.float64), - shape=[2], - unit='joule', - description=''' - Average kinetic energy and its standard deviation over this sequence of frames - (i.e., a trajectory, a frame is one section_single_configuration_calculation). - ''', - a_legacy=LegacyDefinition(name='frame_sequence_kinetic_energy_stats')) - - frame_sequence_kinetic_energy = Quantity( - type=np.dtype(np.float64), - shape=['number_of_kinetic_energies_in_sequence'], - unit='joule', - description=''' - Array containing the values of the kinetic energy along this sequence of frames - (i.e., a trajectory, a frame is one section_single_configuration_calculation). If - not all frames have a value the indices of the frames that have a value are stored - in frame_sequence_kinetic_energy_frames. - ''', - a_legacy=LegacyDefinition(name='frame_sequence_kinetic_energy')) - - frame_sequence_local_frames_ref = Quantity( - type=Reference(SectionProxy('section_single_configuration_calculation')), - shape=['number_of_frames_in_sequence'], - description=''' - Reference from each frame (a frame is one - section_single_configuration_calculation) in this section_frame_sequence to the - corresponding section_single_configuration_calculation. Each - section_frame_sequence binds a collection of - section_single_configuration_calculation, because they all belong to, e.g., a - molecular dynamics trajectory, or geometry optimization. The full information for - each frame is stored in section_single_configuration_calculation and this metadata - establishes the link for each frame. - ''', - a_legacy=LegacyDefinition(name='frame_sequence_local_frames_ref')) - - frame_sequence_potential_energy_frames = Quantity( - type=np.dtype(np.int32), - shape=['number_of_potential_energies_in_sequence'], - description=''' - Array containing the strictly increasing indices referring to the frames of - frame_sequence_potential_energy. If not given it defaults to the trivial mapping - 0,1,... - ''', - a_legacy=LegacyDefinition(name='frame_sequence_potential_energy_frames')) - - frame_sequence_potential_energy_stats = Quantity( - type=np.dtype(np.float64), - shape=[2], - unit='joule', - description=''' - Average potential energy and its standard deviation over this sequence of frames - (i.e., a trajectory, a frame is one section_single_configuration_calculation). - ''', - a_legacy=LegacyDefinition(name='frame_sequence_potential_energy_stats')) - - frame_sequence_potential_energy = Quantity( - type=np.dtype(np.float64), - shape=['number_of_potential_energies_in_sequence'], - unit='joule', - description=''' - Array containing the value of the potential energy along this sequence of frames - (i.e., a trajectory, a frame is one section_single_configuration_calculation). - This is equal to energy_total of the corresponding - section_single_configuration_calculation and repeated here in a summary array for - easier access. If not all frames have a value the indices of the frames that have - a value are stored in frame_sequence_potential_energy_frames. - ''', - a_legacy=LegacyDefinition(name='frame_sequence_potential_energy')) - - frame_sequence_pressure_frames = Quantity( - type=np.dtype(np.int32), - shape=['number_of_pressure_evaluations_in_sequence'], - description=''' - Array containing the strictly increasing indices referring to the frames of - frame_sequence_pressure. If not given it defaults to the trivial mapping 0,1,... - ''', - a_legacy=LegacyDefinition(name='frame_sequence_pressure_frames')) - - frame_sequence_pressure_stats = Quantity( - type=np.dtype(np.float64), - shape=[2], - unit='pascal', - description=''' - Average pressure (one third of the trace of the stress tensor) and standard - deviation over this sequence of frames (i.e., a trajectory, a frame is one - section_single_configuration_calculation). - ''', - a_legacy=LegacyDefinition(name='frame_sequence_pressure_stats')) - - frame_sequence_pressure = Quantity( - type=np.dtype(np.float64), - shape=['number_of_pressure_evaluations_in_sequence'], - unit='pascal', - description=''' - Array containing the values of the pressure (one third of the trace of the stress - tensor) along this sequence of frames (a frame is one - section_single_configuration_calculation). If not all frames have a value the - indices of the frames that have a value are stored in - frame_sequence_pressure_frames. - ''', - a_legacy=LegacyDefinition(name='frame_sequence_pressure')) - - frame_sequence_temperature_frames = Quantity( - type=np.dtype(np.int32), - shape=['number_of_temperatures_in_sequence'], - description=''' - Array containing the strictly increasing indices referring to the frames of - frame_sequence_temperature. If not given it defaults to the trivial mapping - 0,1,... - ''', - a_legacy=LegacyDefinition(name='frame_sequence_temperature_frames')) - - frame_sequence_temperature_stats = Quantity( - type=np.dtype(np.float64), - shape=[2], - unit='kelvin', - description=''' - Average temperature and its standard deviation over this sequence of frames (i.e., - a trajectory, a frame is one section_single_configuration_calculation). - ''', - a_legacy=LegacyDefinition(name='frame_sequence_temperature_stats')) - - frame_sequence_temperature = Quantity( - type=np.dtype(np.float64), - shape=['number_of_temperatures_in_sequence'], - unit='kelvin', - description=''' - Array containing the values of the instantaneous temperature (a quantity, - proportional to frame_sequence_kinetic_energy, whose ensemble average equals the - thermodynamic temperature) along this sequence of frames (i.e., a trajectory, a - frame is one section_single_configuration_calculation). If not all frames have a - value the indices of the frames that have a value are stored in - frame_sequence_temperature_frames. - ''', - a_legacy=LegacyDefinition(name='frame_sequence_temperature')) - - frame_sequence_time = Quantity( - type=np.dtype(np.float64), - shape=['number_of_frames_in_sequence'], - unit='second', - description=''' - Time along this sequence of frames (i.e., a trajectory, a frame is one - section_single_configuration_calculation). Time start is arbitrary, but when a - sequence is a continuation of another time should be continued too. - ''', - a_legacy=LegacyDefinition(name='frame_sequence_time')) - - frame_sequence_to_sampling_ref = Quantity( - type=Reference(SectionProxy('section_sampling_method')), - shape=[], - description=''' - Reference from the present section_frame_sequence to the section_sampling_method, - that defines the parameters used in this sequence of frames (i.e., a trajectory, a - frame is one section_single_configuration_calculation). - ''', - a_legacy=LegacyDefinition(name='frame_sequence_to_sampling_ref')) - - geometry_optimization_converged = Quantity( - type=bool, - shape=[], - description=''' - Arrays specify whether a geometry optimization is converged. - ''', - a_legacy=LegacyDefinition(name='geometry_optimization_converged')) - - number_of_conserved_quantity_evaluations_in_sequence = Quantity( - type=int, - shape=[], - description=''' - Gives the number of conserved quantity evaluations in this sequence. A sequence is - a trajectory, which can have number_of_frames_in_sequence each representing one - section_single_configuration_calculation section. - ''', - a_legacy=LegacyDefinition(name='number_of_conserved_quantity_evaluations_in_sequence')) - - number_of_frames_in_sequence = Quantity( - type=int, - shape=[], - description=''' - Gives the number of frames in a sequence. A sequence is a trajectory, which can - have number_of_frames_in_sequence each representing one - section_single_configuration_calculation section. - ''', - a_legacy=LegacyDefinition(name='number_of_frames_in_sequence')) - - number_of_kinetic_energies_in_sequence = Quantity( - type=int, - shape=[], - description=''' - Gives the number of kinetic energy evaluations in this sequence of frames, see - frame_sequence_kinetic_energy. - ''', - a_legacy=LegacyDefinition(name='number_of_kinetic_energies_in_sequence')) - - number_of_potential_energies_in_sequence = Quantity( - type=int, - shape=[], - description=''' - Gives the number of potential energies evaluation in this sequence. A sequence is - a trajectory, which can have number_of_frames_in_sequence each representing one - section_single_configuration_calculation section. - ''', - a_legacy=LegacyDefinition(name='number_of_potential_energies_in_sequence')) - - number_of_pressure_evaluations_in_sequence = Quantity( - type=int, - shape=[], - description=''' - Gives the number of pressure evaluations in this sequence. A sequence is a - trajectory, which can have number_of_frames_in_sequence each representing one - section_single_configuration_calculation section. - ''', - a_legacy=LegacyDefinition(name='number_of_pressure_evaluations_in_sequence')) - - number_of_temperatures_in_sequence = Quantity( - type=int, - shape=[], - description=''' - Gives the number of temperature frames (frame_sequence_temperature) used in the - section_frame_sequence. A sequence is a trajectory, which can have - number_of_frames_in_sequence each representing one - section_single_configuration_calculation section. - ''', - a_legacy=LegacyDefinition(name='number_of_temperatures_in_sequence')) - - previous_sequence_ref = Quantity( - type=Reference(SectionProxy('section_frame_sequence')), - shape=[], - description=''' - Contains a reference to the previous sequence. A sequence is a trajectory, which - can have number_of_frames_in_sequence each representing one - section_single_configuration_calculation section. If not given, a start from an - initial configuration is assumed. - ''', - a_legacy=LegacyDefinition(name='previous_sequence_ref')) - - section_frame_sequence_user_quantity = SubSection( - sub_section=SectionProxy('section_frame_sequence_user_quantity'), - repeats=True, - a_legacy=LegacyDefinition(name='section_frame_sequence_user_quantity')) - - section_thermodynamical_properties = SubSection( - sub_section=SectionProxy('section_thermodynamical_properties'), - repeats=True, - a_legacy=LegacyDefinition(name='section_thermodynamical_properties')) - - -class section_gaussian_basis_group(MSection): - ''' - Section that describes a group of Gaussian contractions. Groups allow one to calculate - the primitive Gaussian integrals once for several different linear combinations of - them. This defines basis functions with radial part $f_i(r) = r^{l_i} \\sum_{j} c_{i - j} A(l_i, \\alpha_j) exp(-\\alpha_j r^2)$ where $A(l_i, \\alpha_j)$ is a the - normalization coefficient for primitive Gaussian basis functions. Here, $\\alpha_j$ is - defined in gaussian_basis_group_exponents, $l_i$ is given in gaussian_basis_group_ls, - and $c_{i j}$ is given in gaussian_basis_group_contractions, whereas the radial part - is given by the spherical harmonics $Y_{l m}$. - - This section is defined only if the original basis function uses Gaussian basis - functions, and the sequence of radial functions $f_i$ across all - section_gaussian_basis_group in section_basis_set_atom_centered should match the one - of basis_set_atom_centered_radial_functions. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_gaussian_basis_group')) - - gaussian_basis_group_contractions = Quantity( - type=np.dtype(np.float64), - shape=['number_of_gaussian_basis_group_contractions', 'number_of_gaussian_basis_group_exponents'], - description=''' - contraction coefficients $c_{i j}$ defining the contracted basis functions with - respect to *normalized* primitive Gaussian functions. They define the Gaussian - basis functions as described in section_gaussian_basis_group. - ''', - a_legacy=LegacyDefinition(name='gaussian_basis_group_contractions')) - - gaussian_basis_group_exponents = Quantity( - type=np.dtype(np.float64), - shape=['number_of_gaussian_basis_group_exponents'], - unit='1 / meter ** 2', - description=''' - Exponents $\\alpha_j$ of the Gaussian functions defining this basis set - $exp(-\\alpha_j r^2)$. One should be careful about the units of the coefficients. - ''', - a_legacy=LegacyDefinition(name='gaussian_basis_group_exponents')) - - gaussian_basis_group_ls = Quantity( - type=np.dtype(np.float64), - shape=['number_of_gaussian_basis_group_contractions'], - description=''' - Azimuthal quantum number ($l$) values (of the angular part given by the spherical - harmonic $Y_{l m}$ of the various contracted basis functions). - ''', - a_legacy=LegacyDefinition(name='gaussian_basis_group_ls')) - - number_of_gaussian_basis_group_contractions = Quantity( - type=int, - shape=[], - description=''' - Gives the number of different contractions, i.e. resulting basis functions in a - section_gaussian_basis_group section. - ''', - a_legacy=LegacyDefinition(name='number_of_gaussian_basis_group_contractions')) - - number_of_gaussian_basis_group_exponents = Quantity( - type=int, - shape=[], - description=''' - Gives the number of different Gaussian exponents in a section_gaussian_basis_group - section. - ''', - a_legacy=LegacyDefinition(name='number_of_gaussian_basis_group_exponents')) - - -class section_k_band_normalized(MSection): - ''' - This section stores information on a normalized $k$-band (electronic band structure) - evaluation along one-dimensional pathways in the $k$ (reciprocal) space given in - section_k_band_segment. Eigenvalues calculated at the actual $k$-mesh used for - energy_total evaluations, can be found in the section_eigenvalues section. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_k_band_normalized')) - - k_band_path_normalized_is_standard = Quantity( - type=bool, - shape=[], - description=''' - If the normalized path is along the default path defined in W. Setyawan and S. - Curtarolo, [Comput. Mater. Sci. **49**, 299-312 - (2010)](http://dx.doi.org/10.1016/j.commatsci.2010.05.010). - ''', - a_legacy=LegacyDefinition(name='k_band_path_normalized_is_standard')) - - section_k_band_segment_normalized = SubSection( - sub_section=SectionProxy('section_k_band_segment_normalized'), - repeats=True, - a_legacy=LegacyDefinition(name='section_k_band_segment_normalized')) - - -class section_k_band_segment_normalized(MSection): - ''' - Section collecting the information on a normalized $k$-band segment. This section - stores band structures along a one-dimensional pathway in the $k$ (reciprocal) space. - - Eigenvalues calculated at the actual $k$-mesh used for energy_total evaluations are - defined in section_eigenvalues and the band structures are represented as third-order - tensors: one dimension for the spin channels, one for the sequence of $k$ points for - the segment (given in number_of_k_points_per_segment), and one for the sequence of - eigenvalues at a given $k$ point. The values of the $k$ points in each segment are - stored in band_k_points. The energies and occupation for each eigenstate, at each $k$ - point, segment, and spin channel are stored in band_energies and band_occupations, - respectively. The labels for the segment are specified in band_segm_labels. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_k_band_segment_normalized')) - - band_energies_normalized = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_normalized_k_points_per_segment', 'number_of_normalized_band_segment_eigenvalues'], - unit='joule', - description=''' - $k$-dependent energies of the electronic band segment (electronic band structure) - with respect to the top of the valence band. This is a third-order tensor, with - one dimension used for the spin channels, one for the $k$ points for each segment, - and one for the eigenvalue sequence. - ''', - a_legacy=LegacyDefinition(name='band_energies_normalized')) - - band_k_points_normalized = Quantity( - type=np.dtype(np.float64), - shape=['number_of_normalized_k_points_per_segment', 3], - description=''' - Fractional coordinates of the $k$ points (in the basis of the reciprocal-lattice - vectors) for which the normalized electronic energies are given. - ''', - a_legacy=LegacyDefinition(name='band_k_points_normalized')) - - band_occupations_normalized = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_normalized_k_points_per_segment', 'number_of_normalized_band_segment_eigenvalues'], - description=''' - Occupation of the $k$-points along the normalized electronic band. The size of the - dimensions of this third-order tensor are the same as for the tensor in - band_energies. - ''', - a_legacy=LegacyDefinition(name='band_occupations_normalized')) - - band_segm_labels_normalized = Quantity( - type=str, - shape=[2], - description=''' - Start and end labels of the points in the segment (one-dimensional pathways) - sampled in the $k$-space, using the conventional symbols, e.g., Gamma, K, L. The - coordinates (fractional, in the reciprocal space) of the start and end points for - each segment are given in band_segm_start_end_normalized - ''', - a_legacy=LegacyDefinition(name='band_segm_labels_normalized')) - - band_segm_start_end_normalized = Quantity( - type=np.dtype(np.float64), - shape=[2, 3], - description=''' - Fractional coordinates of the start and end point (in the basis of the reciprocal - lattice vectors) of the segment sampled in the $k$ space. The conventional symbols - (e.g., Gamma, K, L) of the same points are given in band_segm_labels - ''', - a_legacy=LegacyDefinition(name='band_segm_start_end_normalized')) - - number_of_normalized_k_points_per_segment = Quantity( - type=int, - shape=[], - description=''' - Gives the number of $k$ points in the segment of the normalized band structure - (see section_k_band_segment_normalized). - ''', - a_legacy=LegacyDefinition(name='number_of_normalized_k_points_per_segment')) - - -class section_k_band_segment(MSection): - ''' - Section collecting the information on a $k$-band or $q$-band segment. This section - stores band structures along a one-dimensional pathway in the $k$ or $q$ (reciprocal) - space. - - Eigenvalues calculated at the actual $k$-mesh used for energy_total evaluations are - defined in section_eigenvalues and the band structures are represented as third-order - tensors: one dimension for the spin channels, one for the sequence of $k$ or $q$ - points for the segment (given in number_of_k_points_per_segment), and one for the - sequence of eigenvalues at a given $k$ or $q$ point. The values of the $k$ or $q$ - points in each segment are stored in band_k_points. The energies and occupation for - each eigenstate, at each $k$ or $q$ point, segment, and spin channel are stored in - band_energies and band_occupations, respectively. The labels for the segment are - specified in band_segm_labels. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_k_band_segment')) - - band_energies = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_k_points_per_segment', 'number_of_band_segment_eigenvalues'], - unit='joule', - description=''' - $k$-dependent or $q$-dependent energies of the electronic or vibrational band - segment (electronic/vibrational band structure). This is a third-order tensor, - with one dimension used for the spin channels (1 in case of a vibrational band - structure), one for the $k$ or $q$ points for each segment, and one for the - eigenvalue sequence. - ''', - a_legacy=LegacyDefinition(name='band_energies')) - - band_k_points = Quantity( - type=np.dtype(np.float64), - shape=['number_of_k_points_per_segment', 3], - description=''' - Fractional coordinates of the $k$ or $q$ points (in the basis of the reciprocal- - lattice vectors) for which the electronic energy are given. - ''', - a_legacy=LegacyDefinition(name='band_k_points')) - - band_occupations = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_k_points_per_segment', 'number_of_band_segment_eigenvalues'], - description=''' - Occupation of the $k$-points along the electronic band. The size of the dimensions - of this third-order tensor are the same as for the tensor in band_energies. - ''', - a_legacy=LegacyDefinition(name='band_occupations')) - - band_segm_labels = Quantity( - type=str, - shape=[2], - description=''' - Start and end labels of the points in the segment (one-dimensional pathways) - sampled in the $k$-space or $q$-space, using the conventional symbols, e.g., - Gamma, K, L. The coordinates (fractional, in the reciprocal space) of the start - and end points for each segment are given in band_segm_start_end - ''', - a_legacy=LegacyDefinition(name='band_segm_labels')) - - band_segm_start_end = Quantity( - type=np.dtype(np.float64), - shape=[2, 3], - description=''' - Fractional coordinates of the start and end point (in the basis of the reciprocal - lattice vectors) of the segment sampled in the $k$ space. The conventional symbols - (e.g., Gamma, K, L) of the same points are given in band_segm_labels - ''', - a_legacy=LegacyDefinition(name='band_segm_start_end')) - - number_of_k_points_per_segment = Quantity( - type=int, - shape=[], - description=''' - Gives the number of $k$ points in the segment of the band structure, see - section_k_band_segment. - ''', - a_legacy=LegacyDefinition(name='number_of_k_points_per_segment')) - - -class section_band_gap(MSection): - ''' - This section stores information for a band gap within a band structure. - ''' - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_band_gap')) - - value = Quantity( - type=float, - unit="joule", - description=""" - Band gap energy. Value of zero corresponds to a band structure without - a band gap. - """, - a_legacy=LegacyDefinition(name='value') - ) - type = Quantity( - type=MEnum("direct", "indirect"), - description=""" - Type of band gap. - """, - a_legacy=LegacyDefinition(name='type') - ) - conduction_band_min_energy = Quantity( - type=float, - unit="joule", - description=""" - Conduction band minimum energy. - """, - a_legacy=LegacyDefinition(name='conduction_band_min_energy') - ) - valence_band_max_energy = Quantity( - type=float, - unit="joule", - description=""" - Valence band maximum energy. - """, - a_legacy=LegacyDefinition(name='valence_band_max_energy') - ) - conduction_band_min_k_point = Quantity( - type=np.dtype(np.float64), - shape=[3], - unit="1 / meter", - description=""" - Coordinate of the conduction band minimum in k-space. - """, - a_legacy=LegacyDefinition(name='conduction_band_min_k_point') - ) - valence_band_max_k_point = Quantity( - type=np.dtype(np.float64), - shape=[3], - unit="1 / meter", - description=""" - Coordinate of the valence band minimum in k-space. - """, - a_legacy=LegacyDefinition(name='valence_band_max_k_point') - ) - - -class section_brillouin_zone(MSection): - '''Defines a polyhedra for the Brillouin zone in reciprocal space. - ''' - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_brillouin_zone')) - - vertices = Quantity( - type=np.dtype(np.float64), - shape=[3, "1..*"], - description=''' - The vertices of the Brillouin zone corners as 3D coordinates in reciprocal space. - ''', - a_legacy=LegacyDefinition(name='vertices')) - faces = Quantity( - type=np.dtype(np.int32), - shape=["1..*", "3..*"], - description=''' - The faces of the Brillouin zone polyhedron as vertex indices. The - surface normal is determined by a right-hand ordering of the points. - ''', - a_legacy=LegacyDefinition(name='faces')) - - -class section_k_band(MSection): - ''' - This section stores information on a $k$-band (electronic or vibrational band - structure) evaluation along one-dimensional pathways in the $k$ or $q$ (reciprocal) - space given in section_k_band_segment. Eigenvalues calculated at the actual $k$-mesh - used for energy_total evaluations, can be found in the section_eigenvalues section. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_k_band')) - - band_structure_kind = Quantity( - type=str, - shape=[], - description=''' - String to specify the kind of band structure (either electronic or vibrational). - ''', - a_legacy=LegacyDefinition(name='band_structure_kind')) - - reciprocal_cell = Quantity( - type=np.dtype(np.float64), - shape=[3, 3], - unit="1 / meter", - description=""" - The reciprocal cell within which the band structure is calculated. - """, - a_legacy=LegacyDefinition(name='reciprocal_cell') - ) - - brillouin_zone = SubSection( - sub_section=SectionProxy('section_brillouin_zone'), - repeats=False, - a_legacy=LegacyDefinition(name='brillouin_zone')) - - section_band_gap = SubSection( - sub_section=section_band_gap.m_def, - repeats=True, - description=""", - Contains information for band gaps detected in the band structure. - Contains a section for each spin channel in the same order as reported - for the band energies. For channels without a band gap, a band gap - value of zero is reported. - """, - a_legacy=LegacyDefinition(name='section_band_gap') - ) - - is_standard_path = Quantity( - type=bool, - description=""" - Boolean indicating whether the path follows the standard path for this - bravais lattice. The AFLOW standard by Setyawan and Curtarolo is used - (https://doi.org/10.1016/j.commatsci.2010.05.010). - """, - a_legacy=LegacyDefinition(name='is_standard_path') - ) - - section_k_band_segment = SubSection( - sub_section=SectionProxy('section_k_band_segment'), - repeats=True, - a_legacy=LegacyDefinition(name='section_k_band_segment')) - - -class section_method_atom_kind(MSection): - ''' - Every section_method_atom_kind section contains method-related information about a - kind of atom, and is identified by one or more strings stored in - method_atom_kind_label. - - This categorization into atom kinds is more flexible than just atomic species, because - to different atoms of the same species different atom-centered basis sets or pseudo- - potentials may be assigned. For instance, if two different oxygen atoms are assigned - to different basis sets or pseudo-potentials, they have to distinguished into two - different *kinds* of O atoms, by creating two distinct section_method_atom_kind - sections. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_method_atom_kind')) - - method_atom_kind_atom_number = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - Atomic number (number of protons) of this atom kind, use 0 if not an atom. - ''', - a_legacy=LegacyDefinition(name='method_atom_kind_atom_number')) - - method_atom_kind_explicit_electrons = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Number of explicit electrons (often called valence). - ''', - a_legacy=LegacyDefinition(name='method_atom_kind_explicit_electrons')) - - method_atom_kind_label = Quantity( - type=str, - shape=[], - description=''' - String used to identify the atoms of this kind. This should correspond to the - atom_labels of the configuration. It is possible for one atom kind to have - multiple labels (in order to allow two atoms of the same kind to have two - differently defined sets of atom-centered basis functions or two different pseudo- - potentials). Atom kind is typically the symbol of the atomic species but it can be - also a ghost or pseudo-atom. - ''', - a_legacy=LegacyDefinition(name='method_atom_kind_label')) - - method_atom_kind_mass = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='unified_atomic_mass_unit', - description=''' - Mass of the kind of this kind of atoms. - ''', - a_legacy=LegacyDefinition(name='method_atom_kind_mass')) - - method_atom_kind_pseudopotential_name = Quantity( - type=str, - shape=[], - description=''' - Name identifying the pseudopotential used. - ''', - a_legacy=LegacyDefinition(name='method_atom_kind_pseudopotential_name')) - - -class section_method_to_method_refs(MSection): - ''' - Section that describes the relationship between different section_method sections. - - For instance, one calculation is a perturbation performed using a self-consistent - field (SCF) calculation as starting point, or a simulated system is partitioned in - regions with different but connected Hamiltonians (e.g., QM/MM, or a region treated - via Kohn-Sham DFT embedded into a region treated via orbital-free DFT). - - The kind of relationship between the method defined in this section and the referenced - one is described by method_to_method_kind. The referenced section section_method is - identified via method_to_method_ref (typically used for a section_method section in - the same section_run) or method_to_method_external_url. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_method_to_method_refs')) - - method_to_method_external_url = Quantity( - type=str, - shape=[], - description=''' - URL used to reference an externally stored section_method. The kind of - relationship between the present and the referenced section_method is specified by - method_to_method_kind. - ''', - a_legacy=LegacyDefinition(name='method_to_method_external_url')) - - method_to_method_kind = Quantity( - type=str, - shape=[], - description=''' - String defining the kind of relationship that the referenced section_method has - with the present section_method. Valid values are described in the - [method_to_method_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- - meta-info/wikis/metainfo/method-to-method-kind). Often calculations are connected, - for instance, one calculation is a perturbation performed using a self-consistent - field (SCF) calculation as starting point, or a simulated system is partitioned in - regions with different but connected Hamiltonians (e.g., QM/MM, or a region - treated via Kohn-Sham DFT embedded into a region treated via orbital-free DFT). - Hence, the need of keeping track of these connected calculations. The referenced - section_method is identified via method_to_method_ref (typically used for a - section_method in the same section_run) or method_to_method_external_url. - ''', - a_legacy=LegacyDefinition(name='method_to_method_kind')) - - method_to_method_ref = Quantity( - type=Reference(SectionProxy('section_method')), - shape=[], - description=''' - Reference to a local section_method. If both method_to_method_ref and - method_to_method_external_url are given, then method_to_method_ref is a local copy - of the value contained in method_to_method_external_url. The kind of relationship - between the method defined in the present section_method and the referenced one is - described by method_to_method_kind. - ''', - a_legacy=LegacyDefinition(name='method_to_method_ref')) - - -class section_method(MSection): - ''' - Section containing the various parameters that define the theory and the - approximations (convergence, thresholds,...) to perform a *single configuration - calculation*, see section_single_configuration_calculation. - - *NOTE*: This section does not contain settings for molecular dynamics, geometry - optimization etc. See section frame_sequence for these other settings instead. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_method')) - - basis_set = Quantity( - type=str, - shape=[], - description=''' - Unique string identifying the basis set used for the final wavefunctions - calculated with XC_method. It might identify a class of basis sets, often matches - one of the strings given in any of basis_set_name. - ''', - categories=[settings_numerical_parameter, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='basis_set')) - - calculation_method_current = Quantity( - type=str, - shape=[], - description=''' - String that represents the method used to calculate the energy_current. If the - method is perturbative, this string does not describe the starting point method, - the latter being referenced to by section_method_to_method_refs. For self- - consistent field (SCF) ab initio calculations, for example, this is composed by - concatenating XC_method_current and basis_set. See [calculation_method_current - wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/calculation-method-current) for the details. - ''', - a_legacy=LegacyDefinition(name='calculation_method_current')) - - calculation_method_kind = Quantity( - type=str, - shape=[], - description=''' - Kind of method in calculation_method_current. - - Accepted values are: - - - absolute - - - perturbative. - ''', - a_legacy=LegacyDefinition(name='calculation_method_kind')) - - calculation_method = Quantity( - type=str, - shape=[], - description=''' - String that uniquely represents the method used to calculate energy_total, If the - present calculation_method_current is a perturbative method Y that uses method X - as starting point, this string is automatically created as X@Y, where X is taken - from calculation_method_current and Y from method_to_method_ref. In order to - activate this, method_to_method_kind must have the value starting_point (see the - [method_to_method_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- - meta-info/wikis/metainfo/method-to-method-kind)). - ''', - a_legacy=LegacyDefinition(name='calculation_method')) - - electronic_structure_method = Quantity( - type=str, - shape=[], - description=''' - Non-unique string identifying the used electronic structure method. It is not - unique in the sense that two calculations with the same - electronic_structure_method string may have not been performed with exactly the - same method. The allowed strings are given in the [electronic structure method - wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/electronic-structure-method). - ''', - categories=[settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='electronic_structure_method')) - - k_mesh_points = Quantity( - type=np.dtype(np.float64), - shape=['number_of_k_mesh_points', 3], - description=''' - List of all the k points in the $k$-point mesh. These are the k point used to - evaluate energy_total, and are in fractional coordinates (in the basis of the - reciprocal-lattice vectors). - ''', - categories=[settings_k_points, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='k_mesh_points')) - - k_mesh_weights = Quantity( - type=np.dtype(np.float64), - shape=['number_of_k_mesh_points'], - description=''' - Weights of all the k points in the $k$-point mesh. These are the weights for - k_mesh_points (i.e. the k point used to evaluate energy_total). - ''', - categories=[settings_k_points, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='k_mesh_weights')) - - number_of_k_mesh_points = Quantity( - type=int, - shape=[], - description=''' - number of k points in the mesh (i.e. the k points used to evaluate energy_total). - ''', - categories=[settings_k_points, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='number_of_k_mesh_points')) - - number_of_spin_channels = Quantity( - type=int, - shape=[], - description=''' - Gives the number of spin channels, see section_method. - ''', - a_legacy=LegacyDefinition(name='number_of_spin_channels')) - - relativity_method = Quantity( - type=str, - shape=[], - description=''' - Describes the relativistic treatment used for the calculation of the final energy - and related quantities. If skipped or empty, no relativistic treatment is applied. - ''', - categories=[settings_relativity, settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='relativity_method')) - - scf_max_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Specifies the maximum number of allowed self-consistent field (SCF) iterations in - a calculation run, see section_run. - ''', - categories=[settings_scf], - a_legacy=LegacyDefinition(name='scf_max_iteration')) - - scf_threshold_energy_change = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Specifies the threshold for the energy_total_scf_iteration change between two - subsequent self-consistent field (SCF) iterations. The SCF is considered converged - when the total-energy change between two SCF cycles is below the threshold - (possibly in combination with other criteria). - ''', - categories=[settings_scf], - a_legacy=LegacyDefinition(name='scf_threshold_energy_change')) - - self_interaction_correction_method = Quantity( - type=str, - shape=[], - description=''' - Contains the name for the self-interaction correction (SIC) treatment used to - calculate the final energy and related quantities. If skipped or empty, no special - correction is applied. - - The following SIC methods are available: - - | SIC method | Description | - - | ------------------------- | -------------------------------- | - - | `""` | No correction | - - | `"SIC_AD"` | The average density correction | - - | `"SIC_SOSEX"` | Second order screened exchange | - - | `"SIC_EXPLICIT_ORBITALS"` | (scaled) Perdew-Zunger correction explicitly on a - set of orbitals | - - | `"SIC_MAURI_SPZ"` | (scaled) Perdew-Zunger expression on the spin - density / doublet unpaired orbital | - - | `"SIC_MAURI_US"` | A (scaled) correction proposed by Mauri and co- - workers on the spin density / doublet unpaired orbital | - ''', - categories=[settings_self_interaction_correction, settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='self_interaction_correction_method')) - - smearing_kind = Quantity( - type=str, - shape=[], - description=''' - Specifies the kind of smearing on the electron occupation used to calculate the - free energy (see energy_free) - - Valid values are: - - | Smearing kind | Description | - - | ------------------------- | --------------------------------- | - - | `"empty"` | No smearing is applied | - - | `"gaussian"` | Gaussian smearing | - - | `"fermi"` | Fermi smearing | - - | `"marzari-vanderbilt"` | Marzari-Vanderbilt smearing | - - | `"methfessel-paxton"` | Methfessel-Paxton smearing | - - | `"tetrahedra"` | Interpolation of state energies and occupations - (ignores smearing_width) | - ''', - categories=[settings_smearing], - a_legacy=LegacyDefinition(name='smearing_kind')) - - smearing_width = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Specifies the width of the smearing in energy for the electron occupation used to - calculate the free energy (see energy_free). - - *NOTE:* Not all methods specified in smearing_kind uses this value. - ''', - categories=[settings_smearing], - a_legacy=LegacyDefinition(name='smearing_width')) - - spin_target_multiplicity = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - Stores the target (user-imposed) value of the spin multiplicity $M=2S+1$, where - $S$ is the total spin. It is an integer number. This value is not necessarily the - value obtained at the end of the calculation. See spin_S2 for the converged value - of the spin moment. - ''', - a_legacy=LegacyDefinition(name='spin_target_multiplicity')) - - stress_tensor_method = Quantity( - type=str, - shape=[], - description=''' - Specifies the method used to calculate stress_tensor for, e.g., molecular dynamics - and geometry optimization. - - The allowed values are: - - * numeric - - * analytic - ''', - categories=[settings_stress_tensor], - a_legacy=LegacyDefinition(name='stress_tensor_method')) - - total_charge = Quantity( - type=np.dtype(np.int32), - shape=[], - unit='coulomb', - description=''' - Provides the total amount of charge of the system in a run. - ''', - a_legacy=LegacyDefinition(name='total_charge')) - - van_der_Waals_method = Quantity( - type=str, - shape=[], - description=''' - Describes the Van der Waals method. If skipped or an empty string is used, it - means no Van der Waals correction is applied. - - Allowed values are: - - | Van der Waals method | Description | - - | --------------------- | ----------------------------------------- | - - | `""` | No Van der Waals correction | - - | `"TS"` | A. Tkatchenko and M. Scheffler, [Phys. Rev. Lett. - **102**, 073005 (2009)](http://dx.doi.org/10.1103/PhysRevLett.102.073005) | - - | `"OBS"` | F. Ortmann, F. Bechstedt, and W. G. Schmidt, [Phys. Rev. - B **73**, 205101 (2006)](http://dx.doi.org/10.1103/PhysRevB.73.205101) | - - | `"G06"` | S. Grimme, [J. Comput. Chem. **27**, 1787 - (2006)](http://dx.doi.org/10.1002/jcc.20495) | - - | `"JCHS"` | P. Jurečka, J. Černý, P. Hobza, and D. R. Salahub, - [Journal of Computational Chemistry **28**, 555 - (2007)](http://dx.doi.org/10.1002/jcc.20570) | - - | `"MDB"` | Many-body dispersion. A. Tkatchenko, R. A. Di Stasio Jr, - R. Car, and M. Scheffler, [Physical Review Letters **108**, 236402 - (2012)](http://dx.doi.org/10.1103/PhysRevLett.108.236402) and A. Ambrosetti, A. M. - Reilly, R. A. Di Stasio Jr, and A. Tkatchenko, [The Journal of Chemical Physics - **140**, 18A508 (2014)](http://dx.doi.org/10.1063/1.4865104) | - - | `"XC"` | The method to calculate the Van der Waals energy uses a - non-local functional which is described in section_XC_functionals. | - ''', - categories=[settings_van_der_Waals, settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='van_der_Waals_method')) - - XC_functional = Quantity( - type=str, - shape=[], - description=''' - This value describes a DFT exchange-correlation (XC) functional used for - evaluating the energy value stored in energy_XC_functional and related quantities - (e.g., forces). - - It is a unique short name obtained by combining the data stored in - section_XC_functionals, more specifically by combining different - XC_functional_name as described in the [XC_functional wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- - functional). - ''', - categories=[settings_potential_energy_surface, settings_physical_parameter, settings_XC_functional, settings_XC], - a_legacy=LegacyDefinition(name='XC_functional')) - - XC_method = Quantity( - type=str, - shape=[], - description=''' - Describes the exchange correlation (XC) method used for evaluating the XC energy - (energy_XC). Differently from XC_functional, perturbative treatments are also - accounted for, where the string contains the reference to both the perturbative - (e.g., MP2) and the starting point (e.g, Hartree-Fock) XC method defined in the - section section_method. - - The value consists of XC_method_current concatenated with the `@` character and - the XC method (XC_method) defined in section_method that is referred to by - method_to_method_ref where method_to_method_kind = "starting_point_method". - ''', - categories=[settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='XC_method')) - - XC_method_current = Quantity( - type=str, - shape=[], - description=''' - Identifies the exchange correlation (XC) method used for energy_XC and related - quantities in a standardized short form as a string. - - It is built by joining the values in the following order using the underscore `_` - character: electronic_structure_method, XC_functional, - self_interaction_correction_method, van_der_Waals_method and relativity_method. - - If any of the methods listed in the string contain non-standard settings, then the - first 10 characters of the Base64 URL encoding of SHA 512 checksum of a normalized - JSON with all non-redundant non-derived settings_XC are appended to the the string - preceded by an underscore. - - With empty strings, the underscore `_` character is skipped. - - If the method defined in the section_method section is perturbative, the - XC_method_current contains only the perturbative method, not the starting point - (e.g. the DFT XC functional used as a starting point for a RPA perturbative - calculation). In this case, the string that contains both the perturbative and - starting point method is stored in XC_method. - ''', - categories=[settings_XC, settings_potential_energy_surface], - a_legacy=LegacyDefinition(name='XC_method_current')) - - section_method_atom_kind = SubSection( - sub_section=SectionProxy('section_method_atom_kind'), - repeats=True, - a_legacy=LegacyDefinition(name='section_method_atom_kind')) - - section_method_to_method_refs = SubSection( - sub_section=SectionProxy('section_method_to_method_refs'), - repeats=True, - a_legacy=LegacyDefinition(name='section_method_to_method_refs')) - - section_XC_functionals = SubSection( - sub_section=SectionProxy('section_XC_functionals'), - repeats=True, - a_legacy=LegacyDefinition(name='section_XC_functionals')) - - -class section_original_system(MSection): - ''' - Section containing symmetry information that is specific to the original system. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_original_system')) - - equivalent_atoms_original = Quantity( - type=np.dtype(np.int32), - shape=['number_of_atoms'], - description=''' - Gives a mapping table of atoms to symmetrically independent atoms in the original - cell. This is used to find symmetrically equivalent atoms. - ''', - a_legacy=LegacyDefinition(name='equivalent_atoms_original')) - - wyckoff_letters_original = Quantity( - type=str, - shape=['number_of_atoms'], - description=''' - Wyckoff letters for atoms in the original cell. - ''', - a_legacy=LegacyDefinition(name='wyckoff_letters_original')) - - -class section_primitive_system(MSection): - ''' - Section containing symmetry information that is specific to the primitive system. The - primitive system is derived from the standardized system with a transformation that is - specific to the centring. The transformation matrices can be found e.g. from here: - https://atztogo.github.io/spglib/definition.html#transformation-to-the-primitive-cell - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_primitive_system')) - - atom_positions_primitive = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms_primitive', 3], - description=''' - Atom positions in the primitive cell in reduced units. - ''', - a_legacy=LegacyDefinition(name='atom_positions_primitive')) - - atomic_numbers_primitive = Quantity( - type=np.dtype(np.int32), - shape=['number_of_atoms_primitive'], - description=''' - Atomic numbers in the primitive cell. - ''', - a_legacy=LegacyDefinition(name='atomic_numbers_primitive')) - - equivalent_atoms_primitive = Quantity( - type=np.dtype(np.int32), - shape=['number_of_atoms_primitive'], - description=''' - Gives a mapping table of atoms to symmetrically independent atoms in the primitive - cell. This is used to find symmetrically equivalent atoms. - ''', - a_legacy=LegacyDefinition(name='equivalent_atoms_primitive')) - - lattice_vectors_primitive = Quantity( - type=np.dtype(np.float64), - shape=[3, 3], - unit='meter', - description=''' - Primitive lattice vectors. The vectors are the rows of this matrix. - ''', - a_legacy=LegacyDefinition(name='lattice_vectors_primitive')) - - number_of_atoms_primitive = Quantity( - type=int, - shape=[], - description=''' - Number of atoms in primitive system. - ''', - a_legacy=LegacyDefinition(name='number_of_atoms_primitive')) - - wyckoff_letters_primitive = Quantity( - type=str, - shape=['number_of_atoms_primitive'], - description=''' - Wyckoff letters for atoms in the primitive cell. - ''', - a_legacy=LegacyDefinition(name='wyckoff_letters_primitive')) - - -class section_processor_info(MSection): - ''' - Section with information about a processor that generated or added information to the - current calculation. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_processor_info')) - - processor_id = Quantity( - type=str, - shape=[], - description=''' - Id (name+version) of the processor that generated or added information to the - current calculation. - ''', - a_legacy=LegacyDefinition(name='processor_id')) - - processor_number_of_evaluated_contexts = Quantity( - type=np.dtype(np.int64), - shape=[], - description=''' - number of contexts evaluated with this processor in the current current - calculation. - ''', - a_legacy=LegacyDefinition(name='processor_number_of_evaluated_contexts')) - - processor_number_of_failed_contexts = Quantity( - type=np.dtype(np.int64), - shape=[], - description=''' - number of contexts in the current current calculation that had failure for this - processor. - ''', - a_legacy=LegacyDefinition(name='processor_number_of_failed_contexts')) - - processor_number_of_skipped_contexts = Quantity( - type=np.dtype(np.int64), - shape=[], - description=''' - number of contexts skipped by this processor in the current current calculation. - ''', - a_legacy=LegacyDefinition(name='processor_number_of_skipped_contexts')) - - processor_number_of_successful_contexts = Quantity( - type=np.dtype(np.int64), - shape=[], - description=''' - number of contexts in the current calculation that where successfully handled by - this processor. - ''', - a_legacy=LegacyDefinition(name='processor_number_of_successful_contexts')) - - processor_version_details = Quantity( - type=typing.Any, - shape=[], - description=''' - detailed version information on the processor that generated or added information - to the current calculation. - ''', - a_legacy=LegacyDefinition(name='processor_version_details')) - - -class section_processor_log_event(MSection): - ''' - A log event - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_processor_log_event')) - - processor_log_event_level = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - Level of the logging, a lower number has more priority. The levels are the same as - log4j: FATAL -> 100, ERROR -> 200, WARN -> 300, INFO -> 400, DEBUG -> 500, TRACE - -> 600 - ''', - a_legacy=LegacyDefinition(name='processor_log_event_level')) - - processor_log_event_message = Quantity( - type=str, - shape=[], - description=''' - The log message - ''', - a_legacy=LegacyDefinition(name='processor_log_event_message')) - - -class section_processor_log(MSection): - ''' - log of a processor - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_processor_log')) - - processor_log_processor_id = Quantity( - type=str, - shape=[], - description=''' - The processor id of the processor creating this log - ''', - a_legacy=LegacyDefinition(name='processor_log_processor_id')) - - processor_log_start = Quantity( - type=str, - shape=[], - description=''' - Start of the log (in ansi notation YYYY-MM-TT...) - ''', - a_legacy=LegacyDefinition(name='processor_log_start')) - - section_processor_log_event = SubSection( - sub_section=SectionProxy('section_processor_log_event'), - repeats=True, - a_legacy=LegacyDefinition(name='section_processor_log_event')) - - -class section_prototype(MSection): - ''' - Information on the prototype corresponding to the current section. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_prototype')) - - prototype_aflow_id = Quantity( - type=str, - shape=[], - description=''' - AFLOW id of the prototype (see - http://aflowlib.org/CrystalDatabase/prototype_index.html) identified on the basis - of the space_group and normalized_wyckoff. - ''', - a_legacy=LegacyDefinition(name='prototype_aflow_id')) - - prototype_aflow_url = Quantity( - type=str, - shape=[], - description=''' - Url to the AFLOW definition of the prototype (see - http://aflowlib.org/CrystalDatabase/prototype_index.html) identified on the basis - of the space_group and normalized_wyckoff. - ''', - a_legacy=LegacyDefinition(name='prototype_aflow_url')) - - prototype_assignment_method = Quantity( - type=str, - shape=[], - description=''' - Method used to identify the prototype. - ''', - a_legacy=LegacyDefinition(name='prototype_assignment_method')) - - prototype_label = Quantity( - type=str, - shape=[], - description=''' - Label of the prototype identified on the basis of the space_group and - normalized_wyckoff. The label is in the same format as in the read_prototypes - function: --). - ''', - a_legacy=LegacyDefinition(name='prototype_label')) - - -class section_run(MSection): - ''' - Every section_run represents a single call of a program. What exactly is contained in - a run depends on the run type (see for example section_method and - section_single_configuration_calculation) and the program (see [program_info - ](program_info)). - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_run')) - - calculation_file_uri = Quantity( - type=str, - shape=[], - description=''' - Contains the nomad uri of a raw the data file connected to the current run. There - should be an value for the main_file_uri and all ancillary files. - ''', - a_legacy=LegacyDefinition(name='calculation_file_uri')) - - message_debug_run = Quantity( - type=str, - shape=[], - description=''' - A debugging message of the computational program, associated with a run. - ''', - categories=[message_debug], - a_legacy=LegacyDefinition(name='message_debug_run')) - - message_error_run = Quantity( - type=str, - shape=[], - description=''' - An error message of the computational program, associated with a run. - ''', - categories=[message_info, message_debug, message_error, message_warning], - a_legacy=LegacyDefinition(name='message_error_run')) - - message_info_run = Quantity( - type=str, - shape=[], - description=''' - An information message of the computational program, associated with a run. - ''', - categories=[message_info, message_debug], - a_legacy=LegacyDefinition(name='message_info_run')) - - message_warning_run = Quantity( - type=str, - shape=[], - description=''' - A warning message of the computational program, associated with a run. - ''', - categories=[message_info, message_debug, message_warning], - a_legacy=LegacyDefinition(name='message_warning_run')) - - parsing_message_debug_run = Quantity( - type=str, - shape=[], - description=''' - This field is used for debugging messages of the parsing program associated with a - single configuration calculation, see section_single_configuration_calculation. - ''', - categories=[parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_debug_run')) - - parsing_message_error_run = Quantity( - type=str, - shape=[], - description=''' - This field is used for error messages of the parsing program associated with a - run, see section_run. - ''', - categories=[parsing_message_info, parsing_message_error, parsing_message_warning, parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_error_run')) - - parsing_message_info_run = Quantity( - type=str, - shape=[], - description=''' - This field is used for info messages of the parsing program associated with a run, - see section_run. - ''', - categories=[parsing_message_info, parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_info_run')) - - parsing_message_warning_run = Quantity( - type=str, - shape=[], - description=''' - This field is used for warning messages of the parsing program associated with a - run, see section_run. - ''', - categories=[parsing_message_info, parsing_message_warning, parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_warning_run')) - - program_basis_set_type = Quantity( - type=str, - shape=[], - description=''' - The type of basis set used by the program to represent wave functions. Valid values - are: [`Numeric AOs`, `Gaussians`, `(L)APW+lo`, `plane waves`, `psinc functions`, - `real-space grid`]. - ''', - a_legacy=LegacyDefinition(name='program_basis_set_type')) - - program_compilation_datetime = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Contains the program compilation date and time from *Unix epoch* (00:00:00 UTC on - 1 January 1970) in seconds. For date and times without a timezone, the default - timezone GMT is used. - ''', - categories=[accessory_info, program_info], - a_legacy=LegacyDefinition(name='program_compilation_datetime')) - - program_compilation_host = Quantity( - type=str, - shape=[], - description=''' - Specifies the host on which the program was compiled. - ''', - categories=[accessory_info, program_info], - a_legacy=LegacyDefinition(name='program_compilation_host')) - - program_name = Quantity( - type=str, - shape=[], - description=''' - Specifies the name of the program that generated the data. - ''', - categories=[accessory_info, program_info], - a_legacy=LegacyDefinition(name='program_name')) - - program_version = Quantity( - type=str, - shape=[], - description=''' - Specifies the version of the program that was used. This should be the version - number of an official release, the version tag or a commit id as well as the - location of the repository. - ''', - categories=[accessory_info, program_info], - a_legacy=LegacyDefinition(name='program_version')) - - run_clean_end = Quantity( - type=bool, - shape=[], - description=''' - Indicates whether this run terminated properly (true), or if it was killed or - exited with an error code unequal to zero (false). - ''', - a_legacy=LegacyDefinition(name='run_clean_end')) - - run_hosts = Quantity( - type=typing.Any, - shape=[], - description=''' - An associative list of host(s) that performed this simulation. This is an - associative list that contains program-dependent information (*key*) on how the - host was used (*value*). Useful for debugging purposes. - ''', - categories=[parallelization_info, accessory_info], - a_legacy=LegacyDefinition(name='run_hosts')) - - raw_id = Quantity( - type=str, - shape=[], - description=''' - An optional calculation id, if one is found in the code input/output files. - ''', - a_legacy=LegacyDefinition(name='raw_id')) - - time_run_cpu1_end = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the end time of the run on CPU 1. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_run_cpu1_end')) - - time_run_cpu1_start = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the start time of the run on CPU 1. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_run_cpu1_start')) - - time_run_date_end = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the end date of the run as time since the *Unix epoch* (00:00:00 UTC on 1 - January 1970) in seconds. For date and times without a timezone, the default - timezone GMT is used. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_run_date_end')) - - time_run_date_start = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the start date of the run as time since the *Unix epoch* (00:00:00 UTC on 1 - January 1970) in seconds. For date and times without a timezone, the default - timezone GMT is used. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_run_date_start')) - - time_run_wall_end = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the internal wall-clock time at the end of the run. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_run_wall_end')) - - time_run_wall_start = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the internal wall-clock time from the start of the run. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_run_wall_start')) - - section_basis_set_atom_centered = SubSection( - sub_section=SectionProxy('section_basis_set_atom_centered'), - repeats=True, - a_legacy=LegacyDefinition(name='section_basis_set_atom_centered')) - - section_basis_set_cell_dependent = SubSection( - sub_section=SectionProxy('section_basis_set_cell_dependent'), - repeats=True, - a_legacy=LegacyDefinition(name='section_basis_set_cell_dependent')) - - section_frame_sequence = SubSection( - sub_section=SectionProxy('section_frame_sequence'), - repeats=True, - a_legacy=LegacyDefinition(name='section_frame_sequence')) - - section_method = SubSection( - sub_section=SectionProxy('section_method'), - repeats=True, - a_legacy=LegacyDefinition(name='section_method')) - - section_sampling_method = SubSection( - sub_section=SectionProxy('section_sampling_method'), - repeats=True, - a_legacy=LegacyDefinition(name='section_sampling_method')) - - section_single_configuration_calculation = SubSection( - sub_section=SectionProxy('section_single_configuration_calculation'), - repeats=True, - a_legacy=LegacyDefinition(name='section_single_configuration_calculation')) - - section_system = SubSection( - sub_section=SectionProxy('section_system'), - repeats=True, - a_legacy=LegacyDefinition(name='section_system')) - - -class section_sampling_method(MSection): - ''' - Section containing the settings describing a (potential-energy surface) sampling - method. - - Results and monitored quantities of such sampling are collected in a sequence of - frames, section_frame_sequence. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_sampling_method')) - - ensemble_type = Quantity( - type=str, - shape=[], - description=''' - Kind of sampled ensemble stored in section_frame_sequence; valid values are - defined in [ensemble_type wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad- - meta-info/wikis/metainfo/ensemble-type). - ''', - a_legacy=LegacyDefinition(name='ensemble_type')) - - geometry_optimization_energy_change = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of threshold for the energy_total change between two geometry optimization - steps, as convergence criterion of the geometry_optimization_method. A geometry - optimization is considered converged when the energy_total change between two - geometry optimization steps is below the threshold (possibly in combination with - other criteria) - ''', - categories=[settings_geometry_optimization, settings_sampling], - a_legacy=LegacyDefinition(name='geometry_optimization_energy_change')) - - geometry_optimization_geometry_change = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='meter', - description=''' - Value of threshold for the displacement of the nuclei between two geometry - optimization steps as convergence criterion of the geometry_optimization_method. A - geometry optimization is considered converged when the maximum among the - displacements of the nuclei between two geometry optimization steps is below the - threshold (possibly in combination with other criteria) - ''', - categories=[settings_geometry_optimization, settings_sampling], - a_legacy=LegacyDefinition(name='geometry_optimization_geometry_change')) - - geometry_optimization_method = Quantity( - type=str, - shape=[], - description=''' - Algorithm for the geometry optimization. Allowed values are listed in the - [geometry_optimization_method wiki page](https://gitlab.mpcdf.mpg.de/nomad- - lab/nomad-meta-info/wikis/metainfo/geometry-optimization-method). - ''', - categories=[settings_geometry_optimization, settings_sampling], - a_legacy=LegacyDefinition(name='geometry_optimization_method')) - - geometry_optimization_threshold_force = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='newton', - description=''' - Value of threshold for the force modulus as convergence criterion of the - geometry_optimization_method. A geometry optimization is considered converged when - the maximum of the moduli of the force on each of the atoms is below this - threshold (possibly in combination with other criteria) - ''', - categories=[settings_geometry_optimization, settings_sampling], - a_legacy=LegacyDefinition(name='geometry_optimization_threshold_force')) - - sampling_method_expansion_order = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - Order up to which the potential energy surface was expanded in a Taylor series - (see sampling_method). - ''', - a_legacy=LegacyDefinition(name='sampling_method_expansion_order')) - - sampling_method = Quantity( - type=str, - shape=[], - description=''' - Type of method used to do the sampling. - - Allowed values are: - - | Sampling method | Description | - - | ------------------------------ | -------------------------------- | - - | `"geometry_optimization"` | Geometry optimization | - - | `"molecular_dynamics"` | Molecular dynamics | - - | `"montecarlo"` | (Metropolis) Monte Carlo | - - | `"steered_molecular_dynamics"` | Steered molecular dynamics (with time dependent - external forces) | - - | `"meta_dynamics"` | Biased molecular dynamics with history- - dependent Hamiltonian | - - | `"wang_landau_montecarlo"` | Monte Carlo according to the Wang-Landau - formulation. | - - | `"blue_moon"` | Blue Moon sampling | - - | `"langevin_dynamics"` | Langevin dynamics | - - | `"taylor_expansion"` | Taylor expansion of the potential energy - surface | - ''', - a_legacy=LegacyDefinition(name='sampling_method')) - - -class section_scf_iteration(MSection): - ''' - Every section_scf_iteration represents a self-consistent field (SCF) iteration, see - scf_info, and gives detailed information on the SCF procedure of the specified - quantities. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_scf_iteration')) - - electronic_kinetic_energy_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Electronic kinetic energy as defined in XC_method during the self-consistent field - (SCF) iterations. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='electronic_kinetic_energy_scf_iteration')) - - energy_change_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Stores the change of total energy with respect to the previous self-consistent - field (SCF) iteration. - ''', - categories=[error_estimate_contribution, energy_value], - a_legacy=LegacyDefinition(name='energy_change_scf_iteration')) - - energy_correction_entropy_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Entropy correction to the potential energy to compensate for the change in - occupation so that forces at finite T do not need to keep the change of occupation - in account. The array lists the values of the entropy correction for each self- - consistent field (SCF) iteration. Defined consistently with XC_method. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_correction_entropy_scf_iteration')) - - energy_correction_hartree_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Correction to the density-density electrostatic energy in the sum of eigenvalues - (that uses the mixed density on one side), and the fully consistent density- - density electrostatic energy during the self-consistent field (SCF) iterations. - Defined consistently with XC_method. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_correction_hartree_scf_iteration')) - - energy_electrostatic_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Total electrostatic energy (nuclei + electrons) during each self-consistent field - (SCF) iteration. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_electrostatic_scf_iteration')) - - energy_free_per_atom_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Free energy per atom (whose minimum gives the smeared occupation density - calculated with smearing_kind) calculated with XC_method during the self- - consistent field (SCF) iterations. - ''', - categories=[energy_component_per_atom, energy_value], - a_legacy=LegacyDefinition(name='energy_free_per_atom_scf_iteration')) - - energy_free_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Free energy (whose minimum gives the smeared occupation density calculated with - smearing_kind) calculated with the method described in XC_method during the self- - consistent field (SCF) iterations. - ''', - categories=[energy_component, energy_value, energy_total_potential], - a_legacy=LegacyDefinition(name='energy_free_scf_iteration')) - - energy_hartree_error_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Error in the Hartree (electrostatic) potential energy during each self-consistent - field (SCF) iteration. Defined consistently with XC_method. - ''', - categories=[error_estimate_contribution, energy_value], - a_legacy=LegacyDefinition(name='energy_hartree_error_scf_iteration')) - - energy_sum_eigenvalues_per_atom_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the energy per atom, where the energy is defined as the sum of the - eigenvalues of the Hamiltonian matrix given by XC_method, during each self- - consistent field (SCF) iteration. - ''', - categories=[energy_component_per_atom, energy_value], - a_legacy=LegacyDefinition(name='energy_sum_eigenvalues_per_atom_scf_iteration')) - - energy_sum_eigenvalues_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Sum of the eigenvalues of the Hamiltonian matrix defined by XC_method, during each - self-consistent field (SCF) iteration. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_sum_eigenvalues_scf_iteration')) - - energy_total_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the total electronic energy calculated with the method described in - XC_method during each self-consistent field (SCF) iteration. - ''', - categories=[energy_component, energy_value, energy_total_potential], - a_legacy=LegacyDefinition(name='energy_total_scf_iteration')) - - energy_total_T0_per_atom_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the total energy, calculated with the method described in XC_method per - atom extrapolated to $T=0$, based on a free-electron gas argument, during each - self-consistent field (SCF) iteration. - ''', - categories=[energy_total_potential_per_atom, energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_total_T0_per_atom_scf_iteration')) - - energy_total_T0_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the total energy (or equivalently free energy), calculated with the - method described in XC_method and extrapolated to $T=0$, based on a free-electron - gas argument, during each self-consistent field (SCF) iteration. - ''', - categories=[energy_component, energy_value, energy_total_potential], - a_legacy=LegacyDefinition(name='energy_total_T0_scf_iteration')) - - energy_XC_potential_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value for exchange-correlation (XC) potential energy: the integral of the first - order derivative of the functional stored in XC_functional (integral of - v_xc*electron_density), i.e., the component of XC that is in the sum of the - eigenvalues. Values are given for each self-consistent field (SCF) iteration - (i.e., not the converged value, the latter being stored in energy_XC_potential). - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_XC_potential_scf_iteration')) - - energy_XC_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value for exchange-correlation (XC) energy obtained during each self-consistent - field (SCF) iteration, using the method described in XC_method. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_XC_scf_iteration')) - - spin_S2_scf_iteration = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Stores the value of the total spin moment operator $S^2$ during the self- - consistent field (SCF) iterations of the XC_method. It can be used to calculate - the spin contamination in spin-unrestricted calculations. - ''', - a_legacy=LegacyDefinition(name='spin_S2_scf_iteration')) - - time_scf_iteration_cpu1_end = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the end time of a self-consistent field (SCF) iteration on CPU 1. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_scf_iteration_cpu1_end')) - - time_scf_iteration_cpu1_start = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the start time of a self-consistent field (SCF) iteration on CPU 1. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_scf_iteration_cpu1_start')) - - time_scf_iteration_date_end = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the end date of a self-consistent field (SCF) iteration as time since the - *Unix epoch* (00:00:00 UTC on 1 January 1970) in seconds. For date and times - without a timezone, the default timezone GMT is used. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_scf_iteration_date_end')) - - time_scf_iteration_date_start = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the start date of a self-consistent field (SCF) iteration as time since the - *Unix epoch* (00:00:00 UTC on 1 January 1970) in seconds. For date and times - without a timezone, the default timezone GMT is used. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_scf_iteration_date_start')) - - time_scf_iteration_wall_end = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the internal wall-clock time at the end of a self-consistent field (SCF) - iteration. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_scf_iteration_wall_end')) - - time_scf_iteration_wall_start = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the internal wall-clock time from the start of a self-consistent field - (SCF) iteration. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_scf_iteration_wall_start')) - - -class section_single_configuration_calculation(MSection): - ''' - Every section_single_configuration_calculation section contains the values computed - during a *single configuration calculation*, i.e. a calculation performed on a given - configuration of the system (as defined in section_system) and a given computational - method (e.g., exchange-correlation method, basis sets, as defined in section_method). - - The link between the current section_single_configuration_calculation and the related - section_system and section_method sections is established by the values stored in - single_configuration_calculation_to_system_ref and - single_configuration_to_calculation_method_ref, respectively. - - The reason why information on the system configuration and computational method is - stored separately is that several *single configuration calculations* can be performed - on the same system configuration, viz. several system configurations can be evaluated - with the same computational method. This storage strategy avoids redundancies. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_single_configuration_calculation')) - - atom_forces_free_raw = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms', 3], - unit='newton', - description=''' - Forces acting on the atoms, calculated as minus gradient of energy_free, - **without** constraints. The derivatives with respect to displacements of nuclei - are evaluated in Cartesian coordinates. The (electronic) energy_free contains the - change in (fractional) occupation of the electronic eigenstates, which are - accounted for in the derivatives, yielding a truly energy-conserved quantity. - These forces may contain unitary transformations (center-of-mass translations and - rigid rotations for non-periodic systems) that are normally filtered separately - (see atom_forces_free for the filtered counterpart). Forces due to constraints - such as fixed atoms, distances, angles, dihedrals, etc. are also considered - separately (see atom_forces_free for the filtered counterpart). - ''', - categories=[atom_forces_type], - a_legacy=LegacyDefinition(name='atom_forces_free_raw')) - - atom_forces_free = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms', 3], - unit='newton', - description=''' - Forces acting on the atoms, calculated as minus gradient of energy_free, - **including** constraints, if present. The derivatives with respect to - displacements of the nuclei are evaluated in Cartesian coordinates. The - (electronic) energy_free contains the information on the change in (fractional) - occupation of the electronic eigenstates, which are accounted for in the - derivatives, yielding a truly energy-conserved quantity. In addition, these forces - are obtained by filtering out the unitary transformations (center-of-mass - translations and rigid rotations for non-periodic systems, see - atom_forces_free_raw for the unfiltered counterpart). Forces due to constraints - such as fixed atoms, distances, angles, dihedrals, etc. are included (see - atom_forces_free_raw for the unfiltered counterpart). - ''', - categories=[atom_forces_type], - a_legacy=LegacyDefinition(name='atom_forces_free')) - - atom_forces_raw = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms', 3], - unit='newton', - description=''' - Forces acting on the atoms, calculated as minus gradient of energy_total, - **without** constraints. The derivatives with respect to displacements of the - nuclei are evaluated in Cartesian coordinates. These forces may contain unitary - transformations (center-of-mass translations and rigid rotations for non-periodic - systems) that are normally filtered separately (see atom_forces for the filtered - counterpart). Forces due to constraints such as fixed atoms, distances, angles, - dihedrals, etc. are also considered separately (see atom_forces for the filtered - counterpart). - ''', - categories=[atom_forces_type], - a_legacy=LegacyDefinition(name='atom_forces_raw')) - - atom_forces_T0_raw = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms', 3], - unit='newton', - description=''' - Forces acting on the atoms, calculated as minus gradient of energy_total_T0, - **without** constraints. The derivatives with respect to displacements of the - nuclei are evaluated in Cartesian coordinates. These forces may contain unitary - transformations (center-of-mass translations and rigid rotations for non-periodic - systems) that are normally filtered separately (see atom_forces_T0 for the - filtered counterpart). Forces due to constraints such as fixed atoms, distances, - angles, dihedrals, etc. are also considered separately (see atom_forces_T0 for the - filtered counterpart). - ''', - categories=[atom_forces_type], - a_legacy=LegacyDefinition(name='atom_forces_T0_raw')) - - atom_forces_T0 = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms', 3], - unit='newton', - description=''' - Forces acting on the atoms, calculated as minus gradient of energy_total_T0, - **including** constraints, if present. The derivatives with respect to - displacements of the nuclei are evaluated in Cartesian coordinates. In addition, - these forces are obtained by filtering out the unitary transformations (center-of- - mass translations and rigid rotations for non-periodic systems, see - atom_forces_free_T0_raw for the unfiltered counterpart). Forces due to constraints - such as fixed atoms, distances, angles, dihedrals, etc. are also included (see - atom_forces_free_T0_raw for the unfiltered counterpart). - ''', - categories=[atom_forces_type], - a_legacy=LegacyDefinition(name='atom_forces_T0')) - - atom_forces = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms', 3], - unit='newton', - description=''' - Forces acting on the atoms, calculated as minus gradient of energy_total, - **including** constraints, if present. The derivatives with respect to - displacements of nuclei are evaluated in Cartesian coordinates. In addition, these - forces are obtained by filtering out the unitary transformations (center-of-mass - translations and rigid rotations for non-periodic systems, see - atom_forces_free_raw for the unfiltered counterpart). Forces due to constraints - such as fixed atoms, distances, angles, dihedrals, etc. are included (see - atom_forces_raw for the unfiltered counterpart). - ''', - categories=[atom_forces_type], - a_legacy=LegacyDefinition(name='atom_forces')) - - electronic_kinetic_energy = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Self-consistent electronic kinetic energy as defined in XC_method. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='electronic_kinetic_energy')) - - energy_C = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Correlation (C) energy calculated with the method described in XC_functional. - ''', - categories=[energy_component, energy_value, energy_type_C], - a_legacy=LegacyDefinition(name='energy_C')) - - energy_correction_entropy = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Entropy correction to the potential energy to compensate for the change in - occupation so that forces at finite T do not need to keep the change of occupation - in account. Defined consistently with XC_method. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_correction_entropy')) - - energy_correction_hartree = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Correction to the density-density electrostatic energy in the sum of eigenvalues - (that uses the mixed density on one side), and the fully consistent density- - density electrostatic energy. Defined consistently with XC_method. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_correction_hartree')) - - energy_current = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the energy calculated with calculation_method_current. energy_current is - equal to energy_total for non-perturbative methods. For perturbative methods, - energy_current is equal to the correction: energy_total minus energy_total of the - calculation_to_calculation_ref with calculation_to_calculation_kind = - starting_point (see the [method_to_method_kind wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/method- - to-method-kind)). See also [energy_current wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/energy- - current). - ''', - categories=[energy_component, energy_value, energy_total_potential], - a_legacy=LegacyDefinition(name='energy_current')) - - energy_electrostatic = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Total electrostatic energy (nuclei + electrons), defined consistently with - calculation_method. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_electrostatic')) - - energy_free_per_atom = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Free energy per atom (whose minimum gives the smeared occupation density - calculated with smearing_kind) calculated with XC_method. - ''', - categories=[energy_component_per_atom, energy_value], - a_legacy=LegacyDefinition(name='energy_free_per_atom')) - - energy_free = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Free energy (nuclei + electrons) (whose minimum gives the smeared occupation - density calculated with smearing_kind) calculated with the method described in - XC_method. - ''', - categories=[energy_component, energy_value, energy_total_potential], - a_legacy=LegacyDefinition(name='energy_free')) - - energy_hartree_error = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Error in the Hartree (electrostatic) potential energy. Defined consistently with - XC_method. - ''', - categories=[error_estimate_contribution, energy_value], - a_legacy=LegacyDefinition(name='energy_hartree_error')) - - energy_hartree_fock_X_scaled = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Scaled exact-exchange energy that depends on the mixing parameter of the - functional. For example in hybrid functionals, the exchange energy is given as a - linear combination of exact-energy and exchange energy of an approximate DFT - functional; the exact exchange energy multiplied by the mixing coefficient of the - hybrid functional would be stored in this metadata. Defined consistently with - XC_method. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_hartree_fock_X_scaled')) - - energy_hartree_fock_X = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Converged exact-exchange (Hartree-Fock) energy. Defined consistently with - XC_method. - ''', - categories=[energy_type_X, energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_hartree_fock_X')) - - energy_method_current = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the energy calculated with the method calculation_method_current. - Depending on calculation_method_kind it might be a total energy or only a - correction. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_method_current')) - - energy_sum_eigenvalues_per_atom = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the energy per atom, where the energy is defined as the sum of the - eigenvalues of the Hamiltonian matrix given by XC_method. - ''', - categories=[energy_component_per_atom, energy_value], - a_legacy=LegacyDefinition(name='energy_sum_eigenvalues_per_atom')) - - energy_sum_eigenvalues = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Sum of the eigenvalues of the Hamiltonian matrix defined by XC_method. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_sum_eigenvalues')) - - energy_T0_per_atom = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the total energy per atom, calculated with the method described in - XC_method and extrapolated to $T=0$, based on a free-electron gas argument. - ''', - categories=[energy_total_potential_per_atom, energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_T0_per_atom')) - - energy_total_T0_per_atom = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the total energy, calculated with the method described in XC_method per - atom extrapolated to $T=0$, based on a free-electron gas argument. - ''', - categories=[energy_total_potential_per_atom, energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_total_T0_per_atom')) - - energy_total_T0 = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the total energy (or equivalently free energy), calculated with the - method described in XC_method and extrapolated to $T=0$, based on a free-electron - gas argument. - ''', - categories=[energy_component, energy_value, energy_total_potential], - a_legacy=LegacyDefinition(name='energy_total_T0')) - - energy_total = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the total energy, calculated with the method described in XC_method and - extrapolated to $T=0$, based on a free-electron gas argument. - ''', - categories=[energy_component, energy_value, energy_total_potential], - a_legacy=LegacyDefinition(name='energy_total')) - - energy_XC_functional = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the exchange-correlation (XC) energy calculated with the functional - stored in XC_functional. - ''', - categories=[energy_type_XC, energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_XC_functional')) - - energy_XC_potential = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the exchange-correlation (XC) potential energy: the integral of the first - order derivative of the functional stored in XC_functional (integral of - v_xc*electron_density), i.e., the component of XC that is in the sum of the - eigenvalues. Value associated with the configuration, should be the most converged - value. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_XC_potential')) - - energy_XC = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the exchange-correlation (XC) energy calculated with the method described - in XC_method. - ''', - categories=[energy_type_XC, energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_XC')) - - energy_X = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value fo the exchange (X) energy calculated with the method described in - XC_method. - ''', - categories=[energy_type_X, energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_X')) - - energy_zero_point = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Value for the converged zero-point vibrations energy calculated using the method - described in zero_point_method , and used in energy_current . - ''', - a_legacy=LegacyDefinition(name='energy_zero_point')) - - hessian_matrix = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms', 'number_of_atoms', 3, 3], - description=''' - The matrix with the second derivative with respect to atom displacements. - ''', - a_legacy=LegacyDefinition(name='hessian_matrix')) - - message_debug_evaluation = Quantity( - type=str, - shape=[], - description=''' - A debugging message of the computational program, associated with a *single - configuration calculation* (see section_single_configuration_calculation). - ''', - categories=[message_debug], - a_legacy=LegacyDefinition(name='message_debug_evaluation')) - - message_error_evaluation = Quantity( - type=str, - shape=[], - description=''' - An error message of the computational program, associated with a *single - configuration calculation* (see section_single_configuration_calculation). - ''', - categories=[message_info, message_debug, message_error, message_warning], - a_legacy=LegacyDefinition(name='message_error_evaluation')) - - message_info_evaluation = Quantity( - type=str, - shape=[], - description=''' - An information message of the computational program, associated with a *single - configuration calculation* (see section_single_configuration_calculation). - ''', - categories=[message_info, message_debug], - a_legacy=LegacyDefinition(name='message_info_evaluation')) - - message_warning_evaluation = Quantity( - type=str, - shape=[], - description=''' - A warning message of the computational program. - ''', - categories=[message_info, message_debug, message_warning], - a_legacy=LegacyDefinition(name='message_warning_evaluation')) - - number_of_scf_iterations = Quantity( - type=int, - shape=[], - description=''' - Gives the number of performed self-consistent field (SCF) iterations at a specfied - level of theory. - ''', - categories=[scf_info], - a_legacy=LegacyDefinition(name='number_of_scf_iterations')) - - parsing_message_debug_evaluation = Quantity( - type=str, - shape=[], - description=''' - This field is used for debugging messages of the parsing program associated with a - run, see section_run. - ''', - categories=[parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_debug_evaluation')) - - parsing_message_error_single_configuration = Quantity( - type=str, - shape=[], - description=''' - This field is used for error messages of the parsing program associated with a - single configuration calculation, see section_single_configuration_calculation. - ''', - categories=[parsing_message_info, parsing_message_error, parsing_message_warning, parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_error_single_configuration')) - - parsing_message_info_single_configuration = Quantity( - type=str, - shape=[], - description=''' - This field is used for info messages of the parsing program associated with a - single configuration calculation, see section_single_configuration_calculation. - ''', - categories=[parsing_message_info, parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_info_single_configuration')) - - parsing_message_warning_evaluation = Quantity( - type=str, - shape=[], - description=''' - This field is used for warning messages of the parsing program associated with a - run, see section_run. - ''', - categories=[parsing_message_info, parsing_message_warning, parsing_message_debug], - a_legacy=LegacyDefinition(name='parsing_message_warning_evaluation')) - - single_configuration_calculation_converged = Quantity( - type=bool, - shape=[], - description=''' - Determines whether a *single configuration calculation* in - section_single_configuration_calculation is converged. - ''', - a_legacy=LegacyDefinition(name='single_configuration_calculation_converged')) - - single_configuration_calculation_to_system_ref = Quantity( - type=Reference(SectionProxy('section_system')), - shape=[], - description=''' - Reference to the system (atomic configuration, cell, ...) that is calculated in - section_single_configuration_calculation. - ''', - categories=[fast_access], - a_legacy=LegacyDefinition(name='single_configuration_calculation_to_system_ref')) - - single_configuration_to_calculation_method_ref = Quantity( - type=Reference(SectionProxy('section_method')), - shape=[], - categories=[fast_access], - description=''' - Reference to the method used for the calculation in - section_single_configuration_calculation. - ''', - a_legacy=LegacyDefinition(name='single_configuration_to_calculation_method_ref')) - - spin_S2 = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Stores the value of the total spin moment operator $S^2$ for the converged - wavefunctions calculated with the XC_method. It can be used to calculate the spin - contamination in spin-unrestricted calculations. - ''', - a_legacy=LegacyDefinition(name='spin_S2')) - - stress_tensor = Quantity( - type=np.dtype(np.float64), - shape=[3, 3], - unit='pascal', - description=''' - Stores the final value of the default stress tensor consistent with energy_total - and calculated with the method specified in stress_tensor_method. - - This value is used (if needed) for, e.g., molecular dynamics and geometry - optimization. Alternative definitions of the stress tensor can be assigned with - stress_tensor_kind - ''', - categories=[stress_tensor_type], - a_legacy=LegacyDefinition(name='stress_tensor')) - - time_calculation = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the wall-clock time needed for a calculation using - calculation_method_current. Basically, it tracks the real time that has been - elapsed from start to end. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_calculation')) - - time_single_configuration_calculation_cpu1_end = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the end time of the *single configuration calculation* (see - section_single_configuration_calculation) on CPU 1. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_single_configuration_calculation_cpu1_end')) - - time_single_configuration_calculation_cpu1_start = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the start time of the *single configuration calculation* (see - section_single_configuration_calculation) on CPU 1. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_single_configuration_calculation_cpu1_start')) - - time_single_configuration_calculation_date_end = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the end date of the *single configuration calculation* (see - section_single_configuration_calculation) as time since the *Unix epoch* (00:00:00 - UTC on 1 January 1970) in seconds. For date and times without a timezone, the - default timezone GMT is used. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_single_configuration_calculation_date_end')) - - time_single_configuration_calculation_date_start = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the start date of the *single configuration calculation* (see - section_single_configuration_calculation) as time since the *Unix epoch* (00:00:00 - UTC on 1 January 1970) in seconds. For date and times without a timezone, the - default timezone GMT is used. - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_single_configuration_calculation_date_start')) - - time_single_configuration_calculation_wall_end = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the internal wall-clock time at the end of the *single configuration - calculation* (see section_single_configuration_calculation). - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_single_configuration_calculation_wall_end')) - - time_single_configuration_calculation_wall_start = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='second', - description=''' - Stores the internal wall-clock time from the start of the *single configuration - calculation* (see section_single_configuration_calculation). - ''', - categories=[time_info, accessory_info], - a_legacy=LegacyDefinition(name='time_single_configuration_calculation_wall_start')) - - zero_point_method = Quantity( - type=str, - shape=[], - description=''' - Describes the zero-point vibrations method. If skipped or an empty string is used, - it means no zero-point vibrations correction is applied. - ''', - a_legacy=LegacyDefinition(name='zero_point_method')) - - enthalpy = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - Value of the calculated enthalpy i.e. energy_total + pressure * volume. - ''', - categories=[energy_component, energy_value], - a_legacy=LegacyDefinition(name='energy_enthalpy')) - - pressure = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='pascal', - description=''' - Value of the pressure of the system. - ''', - a_legacy=LegacyDefinition(name='pressure')) - - temperature = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='kelvin', - description=''' - Value of the temperature of the system. - ''', - a_legacy=LegacyDefinition(name='temperature')) - - time_step = Quantity( - type=int, - shape=[], - description=''' - The number of time steps with respect to the start of the calculation. - ''', - a_legacy=LegacyDefinition(name='time_step')) - - section_atom_projected_dos = SubSection( - sub_section=SectionProxy('section_atom_projected_dos'), - repeats=True, - a_legacy=LegacyDefinition(name='section_atom_projected_dos')) - - section_atomic_multipoles = SubSection( - sub_section=SectionProxy('section_atomic_multipoles'), - repeats=True, - a_legacy=LegacyDefinition(name='section_atomic_multipoles')) - - section_basis_set = SubSection( - sub_section=SectionProxy('section_basis_set'), - repeats=True, - a_legacy=LegacyDefinition(name='section_basis_set')) - - section_calculation_to_calculation_refs = SubSection( - sub_section=SectionProxy('section_calculation_to_calculation_refs'), - repeats=True, - a_legacy=LegacyDefinition(name='section_calculation_to_calculation_refs')) - - section_calculation_to_folder_refs = SubSection( - sub_section=SectionProxy('section_calculation_to_folder_refs'), - repeats=True, - a_legacy=LegacyDefinition(name='section_calculation_to_folder_refs')) - - section_dos = SubSection( - sub_section=SectionProxy('section_dos'), - repeats=True, - a_legacy=LegacyDefinition(name='section_dos')) - - section_eigenvalues = SubSection( - sub_section=SectionProxy('section_eigenvalues'), - repeats=True, - a_legacy=LegacyDefinition(name='section_eigenvalues')) - - section_energy_code_independent = SubSection( - sub_section=SectionProxy('section_energy_code_independent'), - repeats=True, - a_legacy=LegacyDefinition(name='section_energy_code_independent')) - - section_energy_van_der_Waals = SubSection( - sub_section=SectionProxy('section_energy_van_der_Waals'), - repeats=True, - a_legacy=LegacyDefinition(name='section_energy_van_der_Waals')) - - section_energy_contribution = SubSection( - sub_section=SectionProxy('section_energy_contribution'), - repeats=True, - a_legacy=LegacyDefinition(name='section_energy_contribution')) - - section_k_band_normalized = SubSection( - sub_section=SectionProxy('section_k_band_normalized'), - repeats=True, - a_legacy=LegacyDefinition(name='section_k_band_normalized')) - - section_k_band = SubSection( - sub_section=SectionProxy('section_k_band'), - repeats=True, - a_legacy=LegacyDefinition(name='section_k_band')) - - section_scf_iteration = SubSection( - sub_section=SectionProxy('section_scf_iteration'), - repeats=True, - a_legacy=LegacyDefinition(name='section_scf_iteration')) - - section_species_projected_dos = SubSection( - sub_section=SectionProxy('section_species_projected_dos'), - repeats=True, - a_legacy=LegacyDefinition(name='section_species_projected_dos')) - - section_stress_tensor = SubSection( - sub_section=SectionProxy('section_stress_tensor'), - repeats=True, - a_legacy=LegacyDefinition(name='section_stress_tensor')) - - section_volumetric_data = SubSection( - sub_section=SectionProxy('section_volumetric_data'), - repeats=True, - a_legacy=LegacyDefinition(name='section_volumetric_data')) - - -class section_species_projected_dos(MSection): - ''' - Section collecting the information on a species-projected density of states (DOS) - evaluation. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_species_projected_dos')) - - number_of_lm_species_projected_dos = Quantity( - type=int, - shape=[], - description=''' - Gives the number of $l$, $m$ combinations for the species-projected density of - states (DOS) defined in section_species_projected_dos. - ''', - a_legacy=LegacyDefinition(name='number_of_lm_species_projected_dos')) - - number_of_species_projected_dos_values = Quantity( - type=int, - shape=[], - description=''' - Gives the number of energy values for the species-projected density of states - (DOS) defined in section_species_projected_dos. - ''', - a_legacy=LegacyDefinition(name='number_of_species_projected_dos_values')) - - number_of_species = Quantity( - type=int, - shape=[], - description=''' - Gives the number of species for the species-projected density of states (DOS) - defined in section_species_projected_dos. - ''', - a_legacy=LegacyDefinition(name='number_of_species')) - - species_projected_dos_energies_normalized = Quantity( - type=np.dtype(np.float64), - shape=['number_of_species_projected_dos_values'], - unit='joule', - description=''' - Contains the set of discrete energy values with respect to the top of the valence - band for the species-projected density of states (DOS). It is derived from the - species_projected_dos_energies species field. - ''', - a_legacy=LegacyDefinition(name='species_projected_dos_energies_normalized')) - - species_projected_dos_energies = Quantity( - type=np.dtype(np.float64), - shape=['number_of_species_projected_dos_values'], - unit='joule', - description=''' - Contains the set of discrete energy values for the species-projected density of - states (DOS). - ''', - a_legacy=LegacyDefinition(name='species_projected_dos_energies')) - - species_projected_dos_lm = Quantity( - type=np.dtype(np.int32), - shape=['number_of_lm_species_projected_dos', 2], - description=''' - Consists of tuples of $l$ and $m$ values for all given values in the - species_projected_dos_values_lm species field. - - The quantum number $l$ represents the azimuthal quantum number, whereas for the - quantum number $m$, besides the conventional use as magnetic quantum number ($l+1$ - integer values from $-l$ to $l$), a set of different conventions is accepted. The - adopted convention is specified by atom_projected_dos_m_kind. - ''', - a_legacy=LegacyDefinition(name='species_projected_dos_lm')) - - species_projected_dos_m_kind = Quantity( - type=str, - shape=[], - description=''' - Specifies the kind of the integer numbers $m$ used in species_projected_dos_lm. - - Allowed values are listed in the [m_kind wiki - page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind) - and can be (quantum) numbers of - - * spherical - - * polynomial - - * real_orbital - - * integrated - - functions or values. - ''', - a_legacy=LegacyDefinition(name='species_projected_dos_m_kind')) - - species_projected_dos_species_label = Quantity( - type=str, - shape=['number_of_species'], - description=''' - Contains labels of the atomic species for the species-projected density of states - (DOS). - - Differently from atom_labels, which allow more than one label for the same atomic - species (by adding a number or a string to the label), this list is expected to - refer to actual atomic species, i.e. belonging to the periodic table of elements. - Thus, the species-projected DOS are expected to be as many as the different atomic - species in the system. - ''', - a_legacy=LegacyDefinition(name='species_projected_dos_species_label')) - - species_projected_dos_values_lm = Quantity( - type=np.dtype(np.float64), - shape=['number_of_lm_species_projected_dos', 'number_of_spin_channels', 'number_of_species', 'number_of_species_projected_dos_values'], - description=''' - Holds species-projected density of states (DOS) values, divided into contributions - from each $l,m$ channel. - - Here, there are as many species-projected DOS as the number of species, - number_of_species. The list of labels of the species is given in - species_projected_dos_species_label. - ''', - a_legacy=LegacyDefinition(name='species_projected_dos_values_lm')) - - species_projected_dos_values_total = Quantity( - type=np.dtype(np.float64), - shape=['number_of_spin_channels', 'number_of_species', 'number_of_species_projected_dos_values'], - description=''' - Holds species-projected density of states (DOS) values, summed up over all - azimuthal quantum numbers $l$. - - Here, there are as many species-projected DOS as the number of species, - number_of_species. The list of labels of the species is given in - species_projected_dos_species_label. - ''', - a_legacy=LegacyDefinition(name='species_projected_dos_values_total')) - - -class section_springer_material(MSection): - ''' - Every section_springer_material contains results of classification of materials with - the same formula according to Springer Materials - it contains - section_springer_classsification, section_springer_compound, section_springer_id, - section_springer_references - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_springer_material')) - - springer_id = Quantity( - type=str, - shape=[], - description=''' - Id of the classified material according to Springer Materials - ''', - a_legacy=LegacyDefinition(name='springer_id')) - - springer_alphabetical_formula = Quantity( - type=str, - shape=[], - description=''' - The alphabetical formula of the material according to Springer Materials Database - ''', - a_legacy=LegacyDefinition(name='springer_alphabetical_formula')) - - springer_url = Quantity( - type=str, - shape=[], - description=''' - Url to the source page in Springer Materials describing the current entry - ''', - a_legacy=LegacyDefinition(name='springer_url')) - - springer_compound_class = Quantity( - type=str, - shape=['N'], - description=''' - Name of a class of the current compound, as defined in by Springer Materials. This - is a property of the chemical formula of the compound - ''', - a_legacy=LegacyDefinition(name='springer_compound_class')) - - springer_classification = Quantity( - type=str, - shape=['N'], - description=''' - Contains the classification name of the current material according to Springer - Materials - ''', - a_legacy=LegacyDefinition(name='springer_classification')) - - section_springer_id = SubSection( - sub_section=SectionProxy('section_springer_id'), - repeats=True, - a_legacy=LegacyDefinition(name='section_springer_id')) - - -class section_springer_id(MSection): - ''' - Identifiers used by Springer Materials - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_springer_id')) - - -class section_std_system(MSection): - ''' - Section containing symmetry information that is specific to the standardized system. - The standardized system is defined as given by spglib and the details can be found - from https://arxiv.org/abs/1506.01455 - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_std_system')) - - atom_positions_std = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms_std', 3], - description=''' - Standardized atom positions in reduced units. - ''', - a_legacy=LegacyDefinition(name='atom_positions_std')) - - atomic_numbers_std = Quantity( - type=np.dtype(np.int32), - shape=['number_of_atoms_std'], - description=''' - Atomic numbers of the atoms in the standardized cell. - ''', - a_legacy=LegacyDefinition(name='atomic_numbers_std')) - - equivalent_atoms_std = Quantity( - type=np.dtype(np.int32), - shape=['number_of_atoms_std'], - description=''' - Gives a mapping table of atoms to symmetrically independent atoms in the - standardized cell. This is used to find symmetrically equivalent atoms. - ''', - a_legacy=LegacyDefinition(name='equivalent_atoms_std')) - - lattice_vectors_std = Quantity( - type=np.dtype(np.float64), - shape=[3, 3], - unit='meter', - description=''' - Standardized lattice vectors of the conventional cell. The vectors are the rows of - this matrix. - ''', - a_legacy=LegacyDefinition(name='lattice_vectors_std')) - - number_of_atoms_std = Quantity( - type=int, - shape=[], - description=''' - Number of atoms in standardized system. - ''', - a_legacy=LegacyDefinition(name='number_of_atoms_std')) - - wyckoff_letters_std = Quantity( - type=str, - shape=['number_of_atoms_std'], - description=''' - Wyckoff letters for atoms in the standardized cell. - ''', - a_legacy=LegacyDefinition(name='wyckoff_letters_std')) - - -class section_stress_tensor(MSection): - ''' - Section collecting alternative values to stress_tensor that have been calculated. - - This section allows the storage of multiple definitions and evaluated values of the - stress tensor, while only one definition is used for, e.g., molecular dynamics or - geometry optimization (if needed). - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_stress_tensor')) - - stress_tensor_kind = Quantity( - type=str, - shape=[], - description=''' - Specifies the method used to compute the stress tensor stored in - stress_tensor_value. This is an *alternative* to the stress tensor defined in - stress_tensor_method, which is stored in stress_tensor. - - This field allows for multiple definitions and evaluated values of the stress - tensor, while only one definition is used for, e.g., molecular dynamics and - geometry optimization. - ''', - a_legacy=LegacyDefinition(name='stress_tensor_kind')) - - stress_tensor_value = Quantity( - type=np.dtype(np.float64), - shape=[3, 3], - unit='pascal', - description=''' - Contains the value of the stress tensor of the kind defined in stress_tensor_kind. - This is an *alternative* to the stress tensor defined in stress_tensor_method. - - This field allows for multiple definitions and evaluated values of the stress - tensor, while only one definition is used for, e.g., molecular dynamics and - geometry optimization. - ''', - categories=[stress_tensor_type], - a_legacy=LegacyDefinition(name='stress_tensor_value')) - - -class section_symmetry(MSection): - ''' - Section containing information about the symmetry properties of the system. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_symmetry')) - - bravais_lattice = Quantity( - type=str, - shape=[], - description=''' - Identifier for the Bravais lattice in Pearson notation. The first lowercase letter - identifies the crystal family and can be one of the following: a (triclinic), b - (monoclinic), o (orthorhombic), t (tetragonal), h (hexagonal) or c (cubic). The - second uppercase letter identifies the centring and can be one of the following: P - (primitive), S (face centred), I (body centred), R (rhombohedral centring) or F - (all faces centred). - ''', - a_legacy=LegacyDefinition(name='bravais_lattice')) - - choice = Quantity( - type=str, - shape=[], - description=''' - String that specifies the centering, origin and basis vector settings of the 3D - space group that defines the symmetry group of the simulated physical system (see - section_system). Values are as defined by spglib. - ''', - a_legacy=LegacyDefinition(name='choice')) - - crystal_system = Quantity( - type=str, - shape=[], - description=''' - Name of the crystal system. Can be one of the following: triclinic, monoclinic, - orthorhombic, tetragonal, trigonal, hexagonal or cubic. - ''', - a_legacy=LegacyDefinition(name='crystal_system')) - - hall_number = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - The Hall number for this system. - ''', - a_legacy=LegacyDefinition(name='hall_number')) - - hall_symbol = Quantity( - type=str, - shape=[], - description=''' - The Hall symbol for this system. - ''', - a_legacy=LegacyDefinition(name='hall_symbol')) - - international_short_symbol = Quantity( - type=str, - shape=[], - description=''' - Specifies the International Union of Crystallography (IUC) short symbol of the 3D - space group of this system - ''', - a_legacy=LegacyDefinition(name='international_short_symbol')) - - origin_shift = Quantity( - type=np.dtype(np.float64), - shape=[3], - description=''' - Vector $\\mathbf{p}$ from the origin of the standardized system to the origin of - the original system. Together with the matrix $\\mathbf{P}$, found in - space_group_3D_transformation_matrix, the transformation between the standardized - coordinates $\\mathbf{x}_s$ and original coordinates $\\mathbf{x}$ is then given by - $\\mathbf{x}_s = \\mathbf{P} \\mathbf{x} + \\mathbf{p}$. - ''', - a_legacy=LegacyDefinition(name='origin_shift')) - - point_group = Quantity( - type=str, - shape=[], - description=''' - Symbol of the crystallographic point group in the Hermann-Mauguin notation. - ''', - a_legacy=LegacyDefinition(name='point_group')) - - space_group_number = Quantity( - type=np.dtype(np.int32), - shape=[], - description=''' - Specifies the International Union of Crystallography (IUC) number of the 3D space - group of this system. - ''', - a_legacy=LegacyDefinition(name='space_group_number')) - - symmetry_method = Quantity( - type=str, - shape=[], - description=''' - Identifies the source of the symmetry information contained within this section. - If equal to 'spg_normalized' the information comes from a normalization step. - ''', - a_legacy=LegacyDefinition(name='symmetry_method')) - - transformation_matrix = Quantity( - type=np.dtype(np.float64), - shape=[3, 3], - description=''' - Matrix $\\mathbf{P}$ that is used to transform the standardized coordinates to the - original coordinates. Together with the vector $\\mathbf{p}$, found in - space_group_3D_origin_shift, the transformation between the standardized - coordinates $\\mathbf{x}_s$ and original coordinates $\\mathbf{x}$ is then given by - $\\mathbf{x}_s = \\mathbf{P} \\mathbf{x} + \\mathbf{p}$. - ''', - a_legacy=LegacyDefinition(name='transformation_matrix')) - - section_original_system = SubSection( - sub_section=SectionProxy('section_original_system'), - repeats=True, - a_legacy=LegacyDefinition(name='section_original_system')) - - section_primitive_system = SubSection( - sub_section=SectionProxy('section_primitive_system'), - repeats=True, - a_legacy=LegacyDefinition(name='section_primitive_system')) - - section_std_system = SubSection( - sub_section=SectionProxy('section_std_system'), - repeats=True, - a_legacy=LegacyDefinition(name='section_std_system')) - - -class section_system_to_system_refs(MSection): - ''' - Section that describes the relationship between different section_system sections. - - For instance, if a phonon calculation using a finite difference approach is performed - the force evaluation is typically done in a larger supercell but the properties such - as the phonon band structure are still calculated for the primitive cell. - - The kind of relationship between the system defined in this section and the referenced - one is described by system_to_system_kind. The referenced section_system is identified - via system_to_system_ref. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_system_to_system_refs')) - - system_to_system_kind = Quantity( - type=str, - shape=[], - description=''' - String defining the relationship between the referenced section_system and the - present section_system. Often systems are connected for example if a phonon - calculation using finite differences is performed the force ealuation is done in a - larger supercell but properties such as the phonon band structure are still - calculated for the primitive cell. Hence, the need of keeping track of these - connected systems. The referenced system is identified via system_to_system_ref. - ''', - a_legacy=LegacyDefinition(name='system_to_system_kind')) - - system_to_system_ref = Quantity( - type=Reference(SectionProxy('section_system')), - shape=[], - description=''' - Reference to another system. The kind of relationship between the present and the - referenced section_system is specified by system_to_system_kind. - ''', - a_legacy=LegacyDefinition(name='system_to_system_ref')) - - -class section_system(MSection): - ''' - Every section_system contains all needed properties required to describe the simulated - physical system, e.g. the given atomic configuration, the definition of periodic cell - (if present), the external potentials and other parameters. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_system')) - - atom_atom_number = Quantity( - type=np.dtype(np.int32), - shape=['number_of_sites'], - description=''' - Atomic number Z of the atom. - ''', - a_legacy=LegacyDefinition(name='atom_atom_number')) - - atom_concentrations = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms'], - description=''' - concentration of the atom species in a variable composition, by default it should - be considered an array of ones. Summing these should give the number_of_sites - ''', - a_legacy=LegacyDefinition(name='atom_concentrations')) - - atom_labels = Quantity( - type=str, - shape=['number_of_atoms'], - aliases=['elements'], - description=''' - Labels of the atoms. These strings identify the atom kind and conventionally start - with the symbol of the atomic species, possibly followed by the atomic number. The - same atomic species can be labeled with more than one atom_labels in order to - distinguish, e.g., atoms of the same species assigned to different atom-centered - basis sets or pseudo-potentials, or simply atoms in different locations in the - structure (e.g., bulk and surface). These labels can also be used for *particles* - that do not correspond to physical atoms (e.g., ghost atoms in some codes using - atom-centered basis sets). This metadata defines a configuration and is therefore - required. - ''', - categories=[configuration_core], - a_legacy=LegacyDefinition(name='atom_labels')) - - atom_positions = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms', 3], - unit='meter', - description=''' - Positions of all the atoms, in Cartesian coordinates. This metadata defines a - configuration and is therefore required. For alloys where concentrations of - species are given for each site in the unit cell, it stores the position of the - sites. - ''', - categories=[configuration_core], - a_legacy=LegacyDefinition(name='atom_positions')) - - atom_species = Quantity( - type=np.dtype(np.int32), - shape=['number_of_atoms'], - description=''' - Species of the atom (normally the atomic number Z, 0 or negative for unidentifed - species or particles that are not atoms. - ''', - a_legacy=LegacyDefinition(name='atom_species')) - - atom_velocities = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms', 3], - unit='meter / second', - description=''' - Velocities of the nuclei, defined as the change in Cartesian coordinates of the - nuclei with respect to time. - ''', - a_legacy=LegacyDefinition(name='atom_velocities')) - - configuration_periodic_dimensions = Quantity( - type=bool, - shape=[3], - description=''' - Array labeling which of the lattice vectors use periodic boundary conditions. Note - for the parser developers: This value is not expected to be given for each - section_single_configuration_calculation. It is assumed to be valid from the - section_single_configuration_calculation where it is defined for all subsequent - section_single_configuration_calculation in section_run, until redefined. - ''', - categories=[configuration_core], - a_legacy=LegacyDefinition(name='configuration_periodic_dimensions')) - - configuration_raw_gid = Quantity( - type=str, - shape=[], - description=''' - checksum of the configuration_core, i.e. the geometry of the system. The values - are not normalized in any way so equivalent configurations might have different - values - ''', - a_legacy=LegacyDefinition(name='configuration_raw_gid')) - - embedded_system = Quantity( - type=bool, - shape=[], - description=''' - Is the system embedded into a host geometry?. - ''', - categories=[configuration_core], - a_legacy=LegacyDefinition(name='embedded_system')) - - lattice_vectors = Quantity( - type=np.dtype(np.float64), - shape=[3, 3], - unit='meter', - description=''' - Holds the lattice vectors (in Cartesian coordinates) of the simulation cell. The - last (fastest) index runs over the $x,y,z$ Cartesian coordinates, and the first - index runs over the 3 lattice vectors. - ''', - categories=[configuration_core], - a_legacy=LegacyDefinition(name='lattice_vectors')) - - local_rotations = Quantity( - type=np.dtype(np.float64), - shape=['number_of_atoms', 3, 3], - description=''' - A rotation matrix defining the orientation of each atom. If the rotation matrix - only needs to be specified for some atoms, the remaining atoms should set it to - the zero matrix (not the identity!) - ''', - a_legacy=LegacyDefinition(name='local_rotations')) - - number_of_atoms = Quantity( - type=int, - shape=[], - description=''' - Stores the total number of atoms used in the calculation. For alloys where - concentrations of species are given for each site in the unit cell, it stores the - number of sites. - ''', - a_legacy=LegacyDefinition(name='number_of_atoms')) - - number_of_sites = Quantity( - type=int, - shape=[], - description=''' - number of sites in a variable composition representation. By default (no variable - composition) it is the same as number_of_atoms. - ''', - a_legacy=LegacyDefinition(name='number_of_sites')) - - SC_matrix = Quantity( - type=np.dtype(np.int32), - shape=[3, 3], - description=''' - Specifies the matrix that transforms the unit-cell into the super-cell in which - the actual calculation is performed. - ''', - a_legacy=LegacyDefinition(name='SC_matrix')) - - simulation_cell = Quantity( - type=np.dtype(np.float64), - shape=[3, 3], - unit='meter', - description=''' - DEPRECATED, use lattice_vectors instead. Holds the lattice vectors (in Cartesian - coordinates) of the simulation cell. The last (fastest) index runs over the - $x,y,z$ Cartesian coordinates, and the first index runs over the 3 lattice - vectors. - ''', - categories=[configuration_core], - a_legacy=LegacyDefinition(name='simulation_cell')) - - symmorphic = Quantity( - type=bool, - shape=[], - description=''' - Is the space group symmorphic? Set to True if all translations are zero. - ''', - a_legacy=LegacyDefinition(name='symmorphic')) - - system_composition = Quantity( - type=str, - shape=[], - description=''' - Composition, i.e. cumulative chemical formula with atoms ordered by decreasing - atomic number Z. - ''', - a_legacy=LegacyDefinition(name='system_composition')) - - system_configuration_consistent = Quantity( - type=bool, - shape=[], - description=''' - Flag set is the configuration is consistent - ''', - a_legacy=LegacyDefinition(name='system_configuration_consistent')) - - system_name = Quantity( - type=str, - shape=[], - description=''' - Specifies the name of the system. This information is provided by the user in some - codes and is stored here for debugging or visualization purposes. - ''', - a_legacy=LegacyDefinition(name='system_name')) - - system_reweighted_composition = Quantity( - type=str, - shape=[], - description=''' - Composition, i.e. cumulative chemical with atoms ordered by decreasing atomic - number Z reweighted so that the sum is close to 100, and values are rounded up, - and are stable (i.e. it is a fixed point). - ''', - a_legacy=LegacyDefinition(name='system_reweighted_composition')) - - system_type = Quantity( - type=str, - shape=[], - description=''' - Type of the system - ''', - a_legacy=LegacyDefinition(name='system_type')) - - time_reversal_symmetry = Quantity( - type=bool, - shape=[], - description=''' - Is time-reversal symmetry present? - ''', - a_legacy=LegacyDefinition(name='time_reversal_symmetry')) - - chemical_composition = Quantity( - type=str, - shape=[], - description=''' - The chemical composition as full formula of the system, based on atom species. - ''', - a_legacy=LegacyDefinition(name='chemical_composition')) - - chemical_composition_reduced = Quantity( - type=str, - shape=[], - description=''' - The chemical composition as reduced formula of the system, based on atom species. - ''', - a_legacy=LegacyDefinition(name='chemical_composition_reduced')) - - chemical_composition_bulk_reduced = Quantity( - type=str, - shape=[], - description=''' - The chemical composition as reduced bulk formula of the system, based on atom - species. - ''', - a_legacy=LegacyDefinition(name='chemical_composition_bulk_reduced')) - - section_prototype = SubSection( - sub_section=SectionProxy('section_prototype'), - repeats=True, categories=[fast_access], - a_legacy=LegacyDefinition(name='section_prototype')) - - section_springer_material = SubSection( - sub_section=SectionProxy('section_springer_material'), - repeats=True, categories=[fast_access], - a_legacy=LegacyDefinition(name='section_springer_material')) - - section_symmetry = SubSection( - sub_section=SectionProxy('section_symmetry'), - repeats=True, categories=[fast_access], - a_legacy=LegacyDefinition(name='section_symmetry')) - - section_system_to_system_refs = SubSection( - sub_section=SectionProxy('section_system_to_system_refs'), - repeats=True, - a_legacy=LegacyDefinition(name='section_system_to_system_refs')) - - -class section_thermodynamical_properties(MSection): - ''' - Section that defines thermodynamical properties about the system in a - section_frame_sequence. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_thermodynamical_properties')) - - helmholz_free_energy = Quantity( - type=np.dtype(np.float64), - shape=['number_of_thermodynamical_property_values'], - unit='joule', - description=''' - Stores the Helmholtz free energy per unit cell at constant volume of a - thermodynamic calculation. - ''', - a_legacy=LegacyDefinition(name='helmholz_free_energy')) - - number_of_thermodynamical_property_values = Quantity( - type=int, - shape=[], - description=''' - Gives the number of thermal properties values available in - section_thermodynamical_properties. - ''', - a_legacy=LegacyDefinition(name='number_of_thermodynamical_property_values')) - - thermodynamical_properties_calculation_method = Quantity( - type=str, - shape=[], - description=''' - Method used to calculate the thermodynamic quantities. - - Valid values: - - * harmonic - ''', - a_legacy=LegacyDefinition(name='thermodynamical_properties_calculation_method')) - - thermodynamical_property_heat_capacity_C_v = Quantity( - type=np.dtype(np.float64), - shape=['number_of_thermodynamical_property_values'], - unit='joule / kelvin', - description=''' - Stores the heat capacity per cell unit at constant volume. - ''', - a_legacy=LegacyDefinition(name='thermodynamical_property_heat_capacity_C_v')) - - @derived( - type=np.dtype(np.float64), - shape=['number_of_thermodynamical_property_values'], - unit='joule / kelvin * kilogram', - description=''' - Stores the specific heat capacity at constant volume. - ''', - a_legacy=LegacyDefinition(name='specific_heat_capacity'), - cached=True - ) - def specific_heat_capacity(self) -> np.array: - """Returns the specific heat capacity by dividing the heat capacity per - cell with the mass of the atoms in the cell. - """ - import nomad.atomutils - s_frame_sequence = self.m_parent - first_frame = s_frame_sequence.frame_sequence_local_frames_ref[0] - system = first_frame.single_configuration_calculation_to_system_ref - atomic_numbers = system.atom_species - mass_per_unit_cell = nomad.atomutils.get_summed_atomic_mass(atomic_numbers) - heat_capacity = self.thermodynamical_property_heat_capacity_C_v - specific_heat_capacity = heat_capacity / mass_per_unit_cell - - return specific_heat_capacity - - thermodynamical_property_temperature = Quantity( - type=np.dtype(np.float64), - shape=['number_of_thermodynamical_property_values'], - unit='kelvin', - description=''' - Specifies the temperatures at which properties such as the Helmholtz free energy - are calculated. - ''', - a_legacy=LegacyDefinition(name='thermodynamical_property_temperature')) - - vibrational_free_energy_at_constant_volume = Quantity( - type=np.dtype(np.float64), - shape=['number_of_thermodynamical_property_values'], - unit='joule', - description=''' - Holds the vibrational free energy per atom at constant volume. - ''', - a_legacy=LegacyDefinition(name='vibrational_free_energy_at_constant_volume')) - - @derived( - type=np.dtype(np.float64), - shape=['number_of_thermodynamical_property_values'], - unit='joule / kilogram', - description=''' - Stores the specific vibrational free energy at constant volume. - ''', - a_legacy=LegacyDefinition(name='specific_vibrational_free_energy_at_constant_volume'), - cached=True - ) - def specific_vibrational_free_energy_at_constant_volume(self) -> np.array: - """Returns the specific vibrational free energy by dividing the vibrational free energy per - cell with the mass of the atoms in the cell. - """ - import nomad.atomutils - s_frame_sequence = self.m_parent - first_frame = s_frame_sequence.frame_sequence_local_frames_ref[0] - system = first_frame.single_configuration_calculation_to_system_ref - atomic_numbers = system.atom_species - n_atoms = len(atomic_numbers) - mass_per_atom = nomad.atomutils.get_summed_atomic_mass(atomic_numbers) / n_atoms - free_energy = self.vibrational_free_energy_at_constant_volume - specific_vibrational_free_energy_at_constant_volume = free_energy / mass_per_atom - - return specific_vibrational_free_energy_at_constant_volume - - -class section_volumetric_data(MSection): - ''' - Section defining a set of volumetric data on a uniform real-space - - grid. - - To store an array (e.g. a density or a potential), define: - - * three grid point displacement vectors ("displacements") - - * number of grid points along each axis ("nx", "ny" and "nz") - - * the origin of the coordinate system, i.e. coordinates of the first grid - - point ("origin") - - * how many spatial functions are represented, e.g., two for a - - normal spin-polarized density ("multiplicity") - - * the values for each grid point ("values") - - * the unit that applies to each value ("units") - - * the kind of array represented by the volumetric data ("kind"). - - Allowed kinds are (please add new kinds as necessary): "density", - - "potential_hartree" and "potential_effective". Densities and - - potentials that are spin-polarized should have multiplicity two. - - Rules for more complex spins are to be decided when necessary. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_volumetric_data')) - - volumetric_data_displacements = Quantity( - type=np.dtype(np.float64), - shape=[3, 3], - unit='meter', - description=''' - displacement vectors between grid points along each axis; same indexing rules as - lattice_vectors. In many cases, displacements and number of points are related to - lattice_vectors through: [displacement] * [number of points + N] = - [lattice_vector],where N is 1 for periodic directions and 0 for non-periodic ones - ''', - a_legacy=LegacyDefinition(name='volumetric_data_displacements')) - - volumetric_data_kind = Quantity( - type=str, - shape=[], - description=''' - The kind of function, e.g. density, potential_hartree, potential_effective. The - unit of measurement for "volumetric_data_values" depends on the kind: Densities - are 1/m^3 and potentials are J/m^3. See [full specification on the - wiki](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- - info/wikis/metainfo/volumetric-data). - ''', - a_legacy=LegacyDefinition(name='volumetric_data_kind')) - - volumetric_data_multiplicity = Quantity( - type=int, - shape=[], - description=''' - number of functions stored - ''', - a_legacy=LegacyDefinition(name='volumetric_data_multiplicity')) - - volumetric_data_nx = Quantity( - type=int, - shape=[], - description=''' - number of points along x axis - ''', - a_legacy=LegacyDefinition(name='volumetric_data_nx')) - - volumetric_data_ny = Quantity( - type=int, - shape=[], - description=''' - number of points along y axis - ''', - a_legacy=LegacyDefinition(name='volumetric_data_ny')) - - volumetric_data_nz = Quantity( - type=int, - shape=[], - description=''' - number of points along z axis - ''', - a_legacy=LegacyDefinition(name='volumetric_data_nz')) - - volumetric_data_origin = Quantity( - type=np.dtype(np.float64), - shape=[3], - description=''' - location of the first grid point; same coordinate system as atom_positions when - applicable. - ''', - a_legacy=LegacyDefinition(name='volumetric_data_origin')) - - volumetric_data_values = Quantity( - type=np.dtype(np.float64), - shape=['volumetric_data_multiplicity', 'volumetric_data_nx', 'volumetric_data_ny', 'volumetric_data_nz'], - description=''' - Array of shape (multiplicity, nx, ny, nz) containing the values. The units of - these values depend on which kind of data the values represent; see - "volumetric_data_kind". - ''', - a_legacy=LegacyDefinition(name='volumetric_data_values')) - - -class section_XC_functionals(MSection): - ''' - Section containing one of the exchange-correlation (XC) functionals for the present - section_method that are combined to form the XC_functional. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_XC_functionals')) - - XC_functional_name = Quantity( - type=str, - shape=[], - description=''' - Provides the name of one of the exchange and/or correlation (XC) functionals - combined in XC_functional. - - The valid unique names that can be used are listed in the [XC_functional wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- - functional). - - *NOTE*: This value should refer to a correlation, an exchange or an exchange- - correlation functional only. - ''', - categories=[settings_physical_parameter], - a_legacy=LegacyDefinition(name='XC_functional_name')) - - XC_functional_parameters = Quantity( - type=typing.Any, - shape=[], - description=''' - Contains an associative list of non-default values of the parameters for the - functional declared in XC_functional_name of the section_XC_functionals section. - - For example, if a calculations using a hybrid XC functional (e.g., HSE06) - specifies a user-given value of the mixing parameter between exact and GGA - exchange, then this non-default value is stored in this metadata. - - The labels and units of these values are defined in the paragraph dedicated to the - specified functional declared in XC_functional_name of the [XC_functional wiki - page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC- - functional). - - If this metadata is not given, the default parameter values for the - XC_functional_name are assumed. - ''', - categories=[settings_physical_parameter], - a_legacy=LegacyDefinition(name='XC_functional_parameters')) - - XC_functional_weight = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Provides the value of the weight for the exchange, correlation, or exchange- - correlation functional declared in XC_functional_name (see - section_XC_functionals). - - This weight is used in the linear combination of the different XC functional names - (XC_functional_name) in different section_XC_functionals sections to form the - XC_functional used for evaluating energy_XC_functional and related quantities. - - If not specified then the default is set to 1. - ''', - categories=[settings_physical_parameter], - a_legacy=LegacyDefinition(name='XC_functional_weight')) - - -class GeometryOptimization(MSection): - ''' - Section containing the results of a geometry_optimization workflow. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_geometry_optimization')) - - geometry_optimization_type = Quantity( - type=str, - shape=[], - description=''' - The type of geometry optimization can either be ionic, cell_shape, cell_volume. - ''', - a_legacy=LegacyDefinition(name='geometry_optimization_type') - ) - - input_energy_difference_tolerance = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - The input energy difference tolerance criterion. - ''', - a_legacy=LegacyDefinition(name='input_energy_difference_tolerance')) - - input_force_maximum_tolerance = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='newton', - description=''' - The input maximum net force tolerance criterion. - ''', - a_legacy=LegacyDefinition(name='input_force_maximum_tolerance')) - - final_energy_difference = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='joule', - description=''' - The difference in the energy between the last two steps during optimization. - ''', - a_legacy=LegacyDefinition(name='final_energy_difference'), - a_search=Search()) - - final_force_maximum = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='newton', - description=''' - The maximum net force in the last optimization step. - ''', - a_legacy=LegacyDefinition(name='final_force_maximum')) - - optimization_steps = Quantity( - type=int, - shape=[], - description=''' - Number of optimization steps. - ''', - a_legacy=LegacyDefinition(name='optimization_steps')) - - -class Phonon(MSection): - ''' - Section containing the results of a phonon workflow. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_phonon')) - - force_calculator = Quantity( - type=str, - shape=[], - description=''' - Name of the program used to calculate the forces. - ''', - a_legacy=LegacyDefinition(name='force_calculator')) - - mesh_density = Quantity( - type=np.dtype(np.float64), - shape=[], - unit='1 / m ** 3', - description=''' - Density of the k-mesh for sampling. - ''', - a_legacy=LegacyDefinition(name='mesh_density'), - a_search=Search()) - - n_imaginary_frequencies = Quantity( - type=int, - shape=[], - description=''' - Number of modes with imaginary frequencies. - ''', - a_legacy=LegacyDefinition(name='n_imaginary_frequencies'), - a_search=Search()) - - random_displacements = Quantity( - type=bool, - shape=[], - description=''' - Identifies if displacements are made randomly. - ''', - a_legacy=LegacyDefinition(name='random_displacements')) - - with_non_analytic_correction = Quantity( - type=bool, - shape=[], - description=''' - Identifies if non-analytical term corrections are applied to dynamical matrix. - ''', - a_legacy=LegacyDefinition(name='with_non_analytic_correction'), - a_search=Search()) - - with_grueneisen_parameters = Quantity( - type=bool, - shape=[], - description=''' - Identifies if Grueneisen parameters are calculated. - ''', - a_legacy=LegacyDefinition(name='with_grueneisen_parameters'), - a_search=Search()) - - -class Elastic(MSection): - ''' - Section containing the results of an elastic workflow. - ''' - - m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_elastic')) - - energy_stress_calculator = Quantity( - type=str, - shape=[], - description=''' - Name of program used to calculate energy or stress. - ''', - a_legacy=LegacyDefinition(name='energy_stress_calculator')) - - elastic_calculation_method = Quantity( - type=str, - shape=[], - description=''' - Method used to calculate elastic constants, can either be energy or stress. - ''', - a_legacy=LegacyDefinition(name='elastic_calculation_method')) - - elastic_constants_order = Quantity( - type=int, - shape=[], - description=''' - Order of the calculated elastic constants. - ''', - a_legacy=LegacyDefinition(name='elastic_constants_order'), - a_search=Search()) - - is_mechanically_stable = Quantity( - type=bool, - shape=[], - description=''' - Indicates if structure is mechanically stable from the calculated values - of the elastic constants. - ''', - a_legacy=LegacyDefinition(name='is_mechanically_stable'), - a_search=Search()) - - fitting_error_maximum = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Maximum error in polynomial fit. - ''', - a_legacy=LegacyDefinition(name='fitting_error_maximum')) - - strain_maximum = Quantity( - type=np.dtype(np.float64), - shape=[], - description=''' - Maximum strain applied to crystal. - ''', - a_legacy=LegacyDefinition(name='strain_maximum')) - - -class MolecularDynamics(MSection): - ''' - Section containing results of molecular dynamics workflow. - ''' - - m_def = Section( - validate=False, a_legacy=LegacyDefinition(name='section_molecular_dynamics')) - - finished_normally = Quantity( - type=bool, - shape=[], - description=''' - Indicates if calculation terminated normally. - ''', - a_legacy=LegacyDefinition(name='finished_normally')) - - with_trajectory = Quantity( - type=bool, - shape=[], - description=''' - Indicates if calculation includes trajectory data. - ''', - a_legacy=LegacyDefinition(name='with_trajectory'), - a_search=Search()) - - with_thermodynamics = Quantity( - type=bool, - shape=[], - description=''' - Indicates if calculation contains thermodynamic data. - ''', - a_legacy=LegacyDefinition(name='with_thermodynamics'), - a_search=Search()) - - -class Workflow(MSection): - ''' - Section containing the results of a workflow. - ''' - - m_def = Section( - validate=False, - a_legacy=LegacyDefinition(name='section_workflow')) - - workflow_type = Quantity( - type=str, - shape=[], - description=''' - The type of calculation workflow. Can be one of geometry_optimization, elastic, - phonon, molecular_dynamics. - ''', - a_legacy=LegacyDefinition(name='workflow_type'), - a_search=Search(statistic_size=4, statistic_order='_count')) - - calculation_result_ref = Quantity( - type=Reference(SectionProxy('section_single_configuration_calculation')), - categories=[fast_access], - shape=[], - description=''' - Reference to calculation result. In the case of geometry_optimization and - molecular dynamics, this corresponds to the final step in the simulation. For the - rest of the workflow types, it refers to the original system. - ''', - a_legacy=LegacyDefinition(name='calculation_result_ref')) - - calculations_ref = Quantity( - type=Reference(SectionProxy('section_single_configuration_calculation')), - shape=['optimization_steps'], - description=''' - List of references to each section_single_configuration_calculation in the - simulation. - ''', - a_legacy=LegacyDefinition(name='calculations_ref')) - - section_geometry_optimization = SubSection( - sub_section=SectionProxy('GeometryOptimization'), categories=[fast_access], - a_legacy=LegacyDefinition(name='section_geometry_optimization')) - - section_phonon = SubSection( - sub_section=SectionProxy('Phonon'), categories=[fast_access], - a_legacy=LegacyDefinition(name='section_phonon')) - - section_elastic = SubSection( - sub_section=SectionProxy('Elastic'), - a_legacy=LegacyDefinition(name='section_elastic')) - - section_molecular_dynamics = SubSection( - sub_section=SectionProxy('MolecularDynamics'), - a_legacy=LegacyDefinition(name='section_molecular_dynamics')) - - -m_package.__init_metainfo__() +from .common_dft import * diff --git a/nomad/datamodel/metainfo/public_old.py b/nomad/datamodel/metainfo/public_old.py new file mode 100644 index 0000000000000000000000000000000000000000..ccc6a49c9f0c611f2a6eb06fbb0b2c4efe4beaaf --- /dev/null +++ b/nomad/datamodel/metainfo/public_old.py @@ -0,0 +1,5942 @@ +# +# Copyright The NOMAD Authors. +# +# This file is part of NOMAD. See https://nomad-lab.eu for further info. +# +# 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. +# + +import numpy as np # pylint: disable=unused-import +import typing # pylint: disable=unused-import +from nomad.metainfo import ( # pylint: disable=unused-import + MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy, + Reference, MEnum, derived +) +from nomad.metainfo.search_extension import Search +from nomad.metainfo.legacy import LegacyDefinition + + +m_package = Package( + name='public_nomadmetainfo_json', + description='None', + a_legacy=LegacyDefinition( + name='public.nomadmetainfo.json')) + + +class fast_access(MCategory): + ''' + Used to mark archive objects that need to be stored in a fast 2nd-tier storage + medium, because they are frequently accessed via archive API. + + If applied to a sub_section, the section will be added to the fast storage. Currently + this only works for *root* sections that are sub_sections of `EntryArchive`. + + If applied to a reference types quantity, the referenced section will also be added + to the fast storage, regardless if the referenced section has the category or not. + ''' + + m_def = Category() + + +class accessory_info(MCategory): + ''' + Information that *in theory* should not affect the results of the calculations (e.g., + timing). + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='accessory_info')) + + +class atom_forces_type(MCategory): + ''' + The types of forces acting on the atoms (i.e., minus derivatives of the specific type + of energy with respect to the atom position). + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='atom_forces_type')) + + +class basis_set_description(MCategory): + ''' + One of the parts building the basis set of the system (e.g., some atom-centered basis + set, plane-waves or both). + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='basis_set_description')) + + +class configuration_core(MCategory): + ''' + Properties defining the current configuration. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='configuration_core')) + + +class conserved_quantity(MCategory): + ''' + A quantity that is preserved during the time propagation (for example, + kinetic+potential energy during NVE). + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='conserved_quantity')) + + +class energy_value(MCategory): + ''' + This metadata stores an energy value. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='energy_value')) + + +class error_estimate_contribution(MCategory): + ''' + An estimate of a partial quantity contributing to the error for a given quantity. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='error_estimate_contribution')) + + +class message_debug(MCategory): + ''' + A debugging message of the computational program. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='message_debug')) + + +class parsing_message_debug(MCategory): + ''' + This field is used for debugging messages of the parsing program. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='parsing_message_debug')) + + +class scf_info(MCategory): + ''' + Contains information on the self-consistent field (SCF) procedure, i.e. the number of + SCF iterations (number_of_scf_iterations) or a section_scf_iteration section with + detailed information on the SCF procedure of specified quantities. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='scf_info')) + + +class settings_numerical_parameter(MCategory): + ''' + A parameter that can influence the convergence, but not the physics (unlike + settings_physical_parameter) + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_numerical_parameter')) + + +class settings_physical_parameter(MCategory): + ''' + A parameter that defines the physical model used. Use settings_numerical_parameter for + parameters that that influence only the convergence/accuracy. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_physical_parameter')) + + +class settings_potential_energy_surface(MCategory): + ''' + Contains parameters that control the potential energy surface. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_potential_energy_surface')) + + +class settings_run(MCategory): + ''' + Contains parameters that control the whole run (but not the *single configuration + calculation*, see section_single_configuration_calculation). + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_run')) + + +class settings_sampling(MCategory): + ''' + Contains parameters controlling the sampling. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_sampling')) + + +class settings_scf(MCategory): + ''' + Contains parameters connected with the convergence of the self-consistent field (SCF) + iterations. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_scf')) + + +class settings_smearing(MCategory): + ''' + Contain parameters that control the smearing of the orbital occupation at finite + electronic temperatures. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_smearing')) + + +class settings_stress_tensor(MCategory): + ''' + Settings to calculate the stress tensor (stress_tensor) consistent with the total + energy of the system given in energy_total. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='settings_stress_tensor')) + + +class stress_tensor_type(MCategory): + ''' + Contains the final value of the default stress tensor (stress_tensor) and/or the value + of the stress tensor (stress_tensor_value) of the kind defined in stress_tensor_kind. + ''' + + m_def = Category( + a_legacy=LegacyDefinition(name='stress_tensor_type')) + + +class energy_component_per_atom(MCategory): + ''' + A value of an energy component per atom, concurring in defining the total energy per + atom. + ''' + + m_def = Category( + categories=[energy_value], + a_legacy=LegacyDefinition(name='energy_component_per_atom')) + + +class energy_component(MCategory): + ''' + A value of an energy component, expected to be an extensive property. + ''' + + m_def = Category( + categories=[energy_value], + a_legacy=LegacyDefinition(name='energy_component')) + + +class energy_type_reference(MCategory): + ''' + This metadata stores an energy used as reference point. + ''' + + m_def = Category( + categories=[energy_value], + a_legacy=LegacyDefinition(name='energy_type_reference')) + + +class error_estimate(MCategory): + ''' + An estimate of the error on the converged (final) value. + ''' + + m_def = Category( + categories=[error_estimate_contribution], + a_legacy=LegacyDefinition(name='error_estimate')) + + +class message_info(MCategory): + ''' + An information message of the computational program. + ''' + + m_def = Category( + categories=[message_debug], + a_legacy=LegacyDefinition(name='message_info')) + + +class parallelization_info(MCategory): + ''' + Contains information on the parallelization of the program, i.e. which parallel + programming language was used and its version, how many cores had been working on the + calculation and the flags and parameters needed to run the parallelization of the + code. + ''' + + m_def = Category( + categories=[accessory_info], + a_legacy=LegacyDefinition(name='parallelization_info')) + + +class parsing_message_info(MCategory): + ''' + This field is used for info messages of the parsing program. + ''' + + m_def = Category( + categories=[parsing_message_debug], + a_legacy=LegacyDefinition(name='parsing_message_info')) + + +class program_info(MCategory): + ''' + Contains information on the program that generated the data, i.e. the program_name, + program_version, program_compilation_host and program_compilation_datetime as direct + children of this field. + ''' + + m_def = Category( + categories=[accessory_info], + a_legacy=LegacyDefinition(name='program_info')) + + +class settings_geometry_optimization(MCategory): + ''' + Contains parameters controlling the geometry optimization. + ''' + + m_def = Category( + categories=[settings_sampling], + a_legacy=LegacyDefinition(name='settings_geometry_optimization')) + + +class settings_k_points(MCategory): + ''' + Contains parameters that control the $k$-point mesh. + ''' + + m_def = Category( + categories=[settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_k_points')) + + +class settings_metadynamics(MCategory): + ''' + Contains parameters that control the metadynamics sampling. + ''' + + m_def = Category( + categories=[settings_sampling], + a_legacy=LegacyDefinition(name='settings_metadynamics')) + + +class settings_molecular_dynamics(MCategory): + ''' + Contains parameters that control the molecular dynamics sampling. + ''' + + m_def = Category( + categories=[settings_sampling], + a_legacy=LegacyDefinition(name='settings_molecular_dynamics')) + + +class settings_Monte_Carlo(MCategory): + ''' + Contains parameters that control the Monte-Carlo sampling. + ''' + + m_def = Category( + categories=[settings_sampling], + a_legacy=LegacyDefinition(name='settings_Monte_Carlo')) + + +class settings_XC(MCategory): + ''' + Contains parameters connected with the definition of the exchange-correlation (XC) + *method*. Here, the term *method* is a more general concept than just *functionals* + and include, e.g., post Hartree-Fock methods, too. + ''' + + m_def = Category( + categories=[settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_XC')) + + +class time_info(MCategory): + ''' + Stores information on the date and timings of the calculation. They are useful for, + e.g., debugging or visualization purposes. + ''' + + m_def = Category( + categories=[accessory_info], + a_legacy=LegacyDefinition(name='time_info')) + + +class energy_total_potential_per_atom(MCategory): + ''' + A value of the total potential energy per atom. Note that a direct comparison may not + be possible because of a difference in the methods for computing total energies and + numerical implementations of various codes might leads to different energy zeros (see + section_energy_code_independent for a code-independent definition of the energy). + ''' + + m_def = Category( + categories=[energy_component, energy_value], + a_legacy=LegacyDefinition(name='energy_total_potential_per_atom')) + + +class energy_total_potential(MCategory): + ''' + A value of the total potential energy. Note that a direct comparison may not be + possible because of a difference in the methods for computing total energies and + numerical implementations of various codes might leads to different energy zeros (see + section_energy_code_independent for a code-independent definition of the energy). + ''' + + m_def = Category( + categories=[energy_component, energy_value], + a_legacy=LegacyDefinition(name='energy_total_potential')) + + +class energy_type_C(MCategory): + ''' + This metadata stores the correlation (C) energy. + ''' + + m_def = Category( + categories=[energy_component, energy_value], + a_legacy=LegacyDefinition(name='energy_type_C')) + + +class energy_type_van_der_Waals(MCategory): + ''' + This metadata stores the converged van der Waals energy. + ''' + + m_def = Category( + categories=[energy_component, energy_value], + a_legacy=LegacyDefinition(name='energy_type_van_der_Waals')) + + +class energy_type_XC(MCategory): + ''' + This metadata stores the exchange-correlation (XC) energy. + ''' + + m_def = Category( + categories=[energy_component, energy_value], + a_legacy=LegacyDefinition(name='energy_type_XC')) + + +class energy_type_X(MCategory): + ''' + This metadata stores the exchange (X) energy. + ''' + + m_def = Category( + categories=[energy_component, energy_value], + a_legacy=LegacyDefinition(name='energy_type_X')) + + +class message_warning(MCategory): + ''' + A warning message of the computational program. + ''' + + m_def = Category( + categories=[message_info, message_debug], + a_legacy=LegacyDefinition(name='message_warning')) + + +class parsing_message_warning(MCategory): + ''' + This field is used for warning messages of the parsing program. + ''' + + m_def = Category( + categories=[parsing_message_info, parsing_message_debug], + a_legacy=LegacyDefinition(name='parsing_message_warning')) + + +class settings_barostat(MCategory): + ''' + Contains parameters controlling the barostat in a molecular dynamics calculation. + ''' + + m_def = Category( + categories=[settings_sampling, settings_molecular_dynamics], + a_legacy=LegacyDefinition(name='settings_barostat')) + + +class settings_integrator(MCategory): + ''' + Contains parameters that control the molecular dynamics (MD) integrator. + ''' + + m_def = Category( + categories=[settings_sampling, settings_molecular_dynamics], + a_legacy=LegacyDefinition(name='settings_integrator')) + + +class settings_post_hartree_fock(MCategory): + ''' + Contains parameters for the post Hartree-Fock method. + ''' + + m_def = Category( + categories=[settings_XC, settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_post_hartree_fock')) + + +class settings_relativity(MCategory): + ''' + Contains parameters and information connected with the relativistic treatment used in + the calculation. + ''' + + m_def = Category( + categories=[settings_XC, settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_relativity')) + + +class settings_self_interaction_correction(MCategory): + ''' + Contains parameters and information connected with the self-interaction correction + (SIC) method being used in self_interaction_correction_method. + ''' + + m_def = Category( + categories=[settings_XC, settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_self_interaction_correction')) + + +class settings_thermostat(MCategory): + ''' + Contains parameters that control the thermostat in the molecular dynamics (MD) + calculations. + ''' + + m_def = Category( + categories=[settings_sampling, settings_molecular_dynamics], + a_legacy=LegacyDefinition(name='settings_thermostat')) + + +class settings_van_der_Waals(MCategory): + ''' + Contain parameters and information connected with the Van der Waals treatment used in + the calculation to compute the Van der Waals energy (energy_van_der_Waals). + ''' + + m_def = Category( + categories=[settings_XC, settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_van_der_Waals')) + + +class settings_XC_functional(MCategory): + ''' + Contain parameters connected with the definition of the exchange-correlation (XC) + functional (see section_XC_functionals and XC_functional). + ''' + + m_def = Category( + categories=[settings_XC, settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_XC_functional')) + + +class message_error(MCategory): + ''' + An error message of the computational program. + ''' + + m_def = Category( + categories=[message_info, message_debug, message_warning], + a_legacy=LegacyDefinition(name='message_error')) + + +class parsing_message_error(MCategory): + ''' + This field is used for error messages of the parsing program. + ''' + + m_def = Category( + categories=[parsing_message_info, parsing_message_warning, parsing_message_debug], + a_legacy=LegacyDefinition(name='parsing_message_error')) + + +class settings_coupled_cluster(MCategory): + ''' + Contains parameters for the coupled-cluster method (CC) in the post Hartree-Fock step. + ''' + + m_def = Category( + categories=[settings_post_hartree_fock, settings_XC, settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_coupled_cluster')) + + +class settings_GW(MCategory): + ''' + Contains parameters for the GW-method in the post Hartree-Fock step, that expands the + self-energy in terms of the single particle Green's function $G$ and the screened + Coulomb interaction $W$. + ''' + + m_def = Category( + categories=[settings_post_hartree_fock, settings_XC, settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_GW')) + + +class settings_MCSCF(MCategory): + ''' + Contains parameters for the multi-configurational self-consistent-field (MCSCF) + method. + ''' + + m_def = Category( + categories=[settings_post_hartree_fock, settings_XC, settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_MCSCF')) + + +class settings_moller_plesset_perturbation_theory(MCategory): + ''' + Contains parameters for Møller–Plesset perturbation theory. + ''' + + m_def = Category( + categories=[settings_post_hartree_fock, settings_XC, settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_moller_plesset_perturbation_theory')) + + +class settings_multi_reference(MCategory): + ''' + Contains parameters for the multi-reference single and double configuration + interaction method. + ''' + + m_def = Category( + categories=[settings_post_hartree_fock, settings_XC, settings_potential_energy_surface], + a_legacy=LegacyDefinition(name='settings_multi_reference')) + + +class archive_context(MSection): + ''' + Contains information relating to an archive. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='archive_context')) + + archive_gid = Quantity( + type=str, + shape=[], + description=''' + unique identifier of an archive. + ''', + a_legacy=LegacyDefinition(name='archive_gid')) + + +class calculation_context(MSection): + ''' + Contains information relating to a calculation. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='calculation_context')) + + calculation_gid = Quantity( + type=str, + shape=[], + description=''' + unique identifier of a calculation. + ''', + a_legacy=LegacyDefinition(name='calculation_gid')) + + +class section_atom_projected_dos(MSection): + ''' + Section collecting the information on an atom projected density of states (DOS) + evaluation. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_atom_projected_dos')) + + atom_projected_dos_energies = Quantity( + type=np.dtype(np.float64), + shape=['number_of_atom_projected_dos_values'], + unit='joule', + description=''' + Array containing the set of discrete energy values for the atom-projected density + (electronic-energy) of states (DOS). + ''', + a_legacy=LegacyDefinition(name='atom_projected_dos_energies')) + + atom_projected_dos_lm = Quantity( + type=np.dtype(np.int32), + shape=['number_of_lm_atom_projected_dos', 2], + description=''' + Tuples of $l$ and $m$ values for which atom_projected_dos_values_lm are given. For + the quantum number $l$ the conventional meaning of azimuthal quantum number is + always adopted. For the integer number $m$, besides the conventional use as + magnetic quantum number ($l+1$ integer values from $-l$ to $l$), a set of + different conventions is accepted (see the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). + The adopted convention is specified by atom_projected_dos_m_kind. + ''', + a_legacy=LegacyDefinition(name='atom_projected_dos_lm')) + + atom_projected_dos_m_kind = Quantity( + type=str, + shape=[], + description=''' + String describing what the integer numbers of $m$ in atom_projected_dos_lm mean. + The allowed values are listed in the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). + ''', + a_legacy=LegacyDefinition(name='atom_projected_dos_m_kind')) + + atom_projected_dos_values_lm = Quantity( + type=np.dtype(np.float64), + shape=['number_of_lm_atom_projected_dos', 'number_of_spin_channels', 'number_of_atoms', 'number_of_atom_projected_dos_values'], + description=''' + Values correspond to the number of states for a given energy (the set of discrete + energy values is given in atom_projected_dos_energies) divided into contributions + from each $l,m$ channel for the atom-projected density (electronic-energy) of + states. Here, there are as many atom-projected DOS as the number_of_atoms, the + list of labels of the atoms and their meanings are in atom_labels. + ''', + a_legacy=LegacyDefinition(name='atom_projected_dos_values_lm')) + + atom_projected_dos_values_total = Quantity( + type=np.dtype(np.float64), + shape=['number_of_spin_channels', 'number_of_atoms', 'number_of_atom_projected_dos_values'], + description=''' + Values correspond to the number of states for a given energy (the set of discrete + energy values is given in atom_projected_dos_energies) divided into contributions + summed up over all $l$ channels for the atom-projected density (electronic-energy) + of states (DOS). Here, there are as many atom-projected DOS as the + number_of_atoms, the list of labels of the atoms and their meanings are in + atom_labels. + ''', + a_legacy=LegacyDefinition(name='atom_projected_dos_values_total')) + + number_of_atom_projected_dos_values = Quantity( + type=int, + shape=[], + description=''' + Gives the number of energy values for the atom-projected density of states (DOS) + based on atom_projected_dos_values_lm and atom_projected_dos_values_total. + ''', + a_legacy=LegacyDefinition(name='number_of_atom_projected_dos_values')) + + number_of_lm_atom_projected_dos = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $l$, $m$ combinations for the atom projected density of states + (DOS) defined in section_atom_projected_dos. + ''', + a_legacy=LegacyDefinition(name='number_of_lm_atom_projected_dos')) + + +class section_atomic_multipoles(MSection): + ''' + Section describing multipoles (charges/monopoles, dipoles, quadrupoles, ...) for each + atom. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_atomic_multipoles')) + + atomic_multipole_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the method used to obtain the electrostatic multipoles + (including the electric charge, dipole, etc.) for each atom. Such multipoles + require a charge-density partitioning scheme, specified by the value of this + metadata. Allowed values are listed in the [atomic_multipole_kind wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/atomic- + multipole-kind). + ''', + a_legacy=LegacyDefinition(name='atomic_multipole_kind')) + + atomic_multipole_lm = Quantity( + type=np.dtype(np.int32), + shape=['number_of_lm_atomic_multipoles', 2], + description=''' + Tuples of $l$ and $m$ values for which the atomic multipoles (including the + electric charge, dipole, etc.) are given. The method used to obtain the multipoles + is specified by atomic_multipole_kind. The meaning of the integer number $l$ is + monopole/charge for $l=0$, dipole for $l=1$, quadrupole for $l=2$, etc. The + meaning of the integer numbers $m$ is specified by atomic_multipole_m_kind. + ''', + a_legacy=LegacyDefinition(name='atomic_multipole_lm')) + + atomic_multipole_m_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the definition for each integer number $m$ in + atomic_multipole_lm. Allowed values are listed in the [m_kind wiki + page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind). + ''', + a_legacy=LegacyDefinition(name='atomic_multipole_m_kind')) + + atomic_multipole_values = Quantity( + type=np.dtype(np.float64), + shape=['number_of_lm_atomic_multipoles', 'number_of_atoms'], + description=''' + Value of the multipoles (including the monopole/charge for $l$ = 0, the dipole for + $l$ = 1, etc.) for each atom, calculated as described in atomic_multipole_kind. + ''', + a_legacy=LegacyDefinition(name='atomic_multipole_values')) + + number_of_lm_atomic_multipoles = Quantity( + type=int, + shape=[], + description=''' + Gives the number of $l$, $m$ combinations for atomic multipoles + atomic_multipole_lm. + ''', + a_legacy=LegacyDefinition(name='number_of_lm_atomic_multipoles')) + + +class section_basis_functions_atom_centered(MSection): + ''' + This section contains the description of the basis functions (at least one function) + of the (atom-centered) basis set defined in section_basis_set_atom_centered. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_basis_functions_atom_centered')) + + +class section_basis_set_atom_centered(MSection): + ''' + This section describes the atom-centered basis set. The main contained information is + a short, non unique but human-interpretable, name for identifying the basis set + (basis_set_atom_centered_short_name), a longer, unique name + (basis_set_atom_centered_unique_name), the atomic number of the atomic species the + basis set is meant for (basis_set_atom_number), and a list of actual basis functions + in the section_basis_functions_atom_centered section. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_basis_set_atom_centered')) + + basis_set_atom_centered_ls = Quantity( + type=np.dtype(np.int32), + shape=['number_of_kinds_in_basis_set_atom_centered'], + description=''' + Azimuthal quantum number ($l$) values (of the angular part given by the spherical + harmonic $Y_{lm}$) of the atom-centered basis function defined in the current + section_basis_set_atom_centered. + ''', + a_legacy=LegacyDefinition(name='basis_set_atom_centered_ls')) + + basis_set_atom_centered_radial_functions = Quantity( + type=np.dtype(np.float64), + shape=['number_of_kinds_in_basis_set_atom_centered', 401, 5], + description=''' + Values of the radial function of the different basis function kinds. The values + are numerically tabulated on a default 0.01-nm equally spaced grid from 0 to 4 nm. + The 5 tabulated values are $r$, $f(r)$, $f'(r)$, $f(r) \\cdot r$, + $\\frac{d}{dr}(f(r) \\cdot r)$. + ''', + a_legacy=LegacyDefinition(name='basis_set_atom_centered_radial_functions')) + + basis_set_atom_centered_short_name = Quantity( + type=str, + shape=[], + description=''' + Code-specific, but explicative, base name for the basis set (not unique). Details + are explained in the [basis_set_atom_centered_short_name wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- + set-atom-centered-short-name), this name should not contain the *atom kind* (to + simplify the use of a single name for multiple elements). + ''', + a_legacy=LegacyDefinition(name='basis_set_atom_centered_short_name')) + + basis_set_atom_centered_unique_name = Quantity( + type=str, + shape=[], + description=''' + Code-specific, but explicative, base name for the basis set (not unique). This + string starts with basis_set_atom_centered_short_name. If the basis set defined in + this section_basis_set_atom_centered is not identical to the default definition + (stored in a database) of the basis set with the same name stored in a database, + then the string is extended by 10 identifiable characters as explained in the + [basis_set_atom_centered_name wiki page](https://gitlab.mpcdf.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/basis-set-atom-centered-unique-name). The + reason for this procedure is that often atom-centered basis sets are obtained by + fine tuning basis sets provided by the code developers or other sources. Each + basis sets, which has normally a standard name, often reported in publications, + has also several parameters that can be tuned. This metadata tries to keep track + of the original basis set and its modifications. This string here defined should + not contain the *atom kind* for which this basis set is intended for, in order to + simplify the use of a single name for multiple *atom kinds* (see atom_labels for + the actual meaning of *atom kind*). + ''', + a_legacy=LegacyDefinition(name='basis_set_atom_centered_unique_name')) + + basis_set_atom_number = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + Atomic number (i.e., number of protons) of the atom for which this basis set is + constructed (0 means unspecified or a pseudo atom). + ''', + a_legacy=LegacyDefinition(name='basis_set_atom_number')) + + number_of_basis_functions_in_basis_set_atom_centered = Quantity( + type=int, + shape=[], + description=''' + Gives the number of different basis functions in a section_basis_set_atom_centered + section. This equals the number of actual coefficients that are specified when + using this basis set. + ''', + a_legacy=LegacyDefinition(name='number_of_basis_functions_in_basis_set_atom_centered')) + + number_of_kinds_in_basis_set_atom_centered = Quantity( + type=int, + shape=[], + description=''' + Gives the number of different *kinds* of radial basis functions in the + section_basis_set_atom_centered section. Specifically, basis functions with the + same $n$ and $l$ quantum numbers are grouped in sets. Each set counts as one + *kind*. + ''', + a_legacy=LegacyDefinition(name='number_of_kinds_in_basis_set_atom_centered')) + + section_basis_functions_atom_centered = SubSection( + sub_section=SectionProxy('section_basis_functions_atom_centered'), + repeats=True, + a_legacy=LegacyDefinition(name='section_basis_functions_atom_centered')) + + section_gaussian_basis_group = SubSection( + sub_section=SectionProxy('section_gaussian_basis_group'), + repeats=True, + a_legacy=LegacyDefinition(name='section_gaussian_basis_group')) + + +class section_basis_set_cell_dependent(MSection): + ''' + Section describing a cell-dependent (atom-independent) basis set, e.g. plane waves. + The contained information is the type of basis set (in basis_set_cell_dependent_kind), + its parameters (e.g., for plane waves in basis_set_planewave_cutoff), and a name that + identifies the actually used basis set (a string combining the type and the + parameter(s), stored in basis_set_cell_dependent_name). + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_basis_set_cell_dependent')) + + basis_set_cell_dependent_kind = Quantity( + type=str, + shape=[], + description=''' + A string defining the type of the cell-dependent basis set (i.e., non atom + centered such as plane-waves). Allowed values are listed in the + [basis_set_cell_dependent_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad- + lab/nomad-meta-info/wikis/metainfo/basis-set-cell-dependent-kind). + ''', + a_legacy=LegacyDefinition(name='basis_set_cell_dependent_kind')) + + basis_set_cell_dependent_name = Quantity( + type=str, + shape=[], + description=''' + A label identifying the cell-dependent basis set (i.e., non atom centered such as + plane-waves). Allowed values are listed in the [basis_set_cell_dependent_name wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- + set-cell-dependent-name). + ''', + a_legacy=LegacyDefinition(name='basis_set_cell_dependent_name')) + + basis_set_planewave_cutoff = Quantity( + type=np.dtype(np.float64), + shape=[], + unit='joule', + description=''' + Spherical cutoff in reciprocal space for a plane-wave basis set. It is the energy + of the highest plan-ewave ($\\frac{\\hbar^2|k+G|^2}{2m_e}$) included in the basis + set. Note that normally this basis set is used for the wavefunctions, and the + density would have 4 times the cutoff, but this actually depends on the use of the + basis set by the method. + ''', + a_legacy=LegacyDefinition(name='basis_set_planewave_cutoff')) + + +class section_basis_set(MSection): + ''' + This section contains references to *all* basis sets used in this + section_single_configuration_calculation. More than one basis set instance per *single + configuration calculation* (see section_single_configuration_calculation) may be + needed. This is true for example, for codes that implement adaptive basis sets along + the self-consistent field (SCF) convergence (e.g., exciting). In such cases, there is + a section_basis_set instance per SCF iteration, if necessary. Another example is + having a basis set for wavefunctions, a different one for the density, an auxiliary + basis set for resolution of identity (RI), etc. + + Supported are the two broad classes of basis sets: *atom-centered* (e.g., Gaussian- + type, numerical atomic orbitals) and *cell-dependent* (like plane waves or real-space + grids, so named because they are typically used for periodic-system calculations and + dependent to the simulated cell as a whole). + + Basis sets used in this section_single_configuration_calculation, belonging to either + class, are defined in the dedicated section: [section_basis_set_cell_dependent + ](section_basis_set_cell_dependent) or section_basis_set_atom_centered. The + correspondence between the basis sets listed in this section and the definition given + in the dedicated sessions is given by the two concrete metadata: + mapping_section_basis_set_cell_dependent and mapping_section_basis_set_atom_centered. + The latter metadata is a list that connects each atom in the system with its basis + set, where the same basis set can be assigned to more than one atom. + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_basis_set')) + + basis_set_kind = Quantity( + type=str, + shape=[], + description=''' + String describing the use of the basis set, i.e, if it used for expanding a wave- + function or an electron density. Allowed values are listed in the [basis_set_kind + wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta- + info/wikis/metainfo/basis-set-kind). + ''', + a_legacy=LegacyDefinition(name='basis_set_kind')) + + basis_set_name = Quantity( + type=str, + shape=[], + description=''' + String identifying the basis set in an unique way. The rules for building this + string are specified in the [basis_set_name wiki + page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis- + set-name). + ''', + a_legacy=LegacyDefinition(name='basis_set_name')) + + mapping_section_basis_set_atom_centered = Quantity( + type=Reference(SectionProxy('section_basis_set_atom_centered')), + shape=['number_of_atoms'], + description=''' + An array of the dimension of number_of_atoms where each atom (identified by the + index in the array) is assigned to an atom-centered basis set, for this + section_single_configuration_calculation. The actual definition of the atom- + centered basis set is in the section_basis_set_atom_centered that is referred to + by this metadata. + ''', + a_legacy=LegacyDefinition(name='mapping_section_basis_set_atom_centered')) + + mapping_section_basis_set_cell_dependent = Quantity( + type=Reference(SectionProxy('section_basis_set_cell_dependent')), + shape=[], + description=''' + Assignment of the cell-dependent (i.e., non atom centered, e.g., plane-waves) + parts of the basis set, which is defined (type, parameters) in + section_basis_set_cell_dependent that is referred to by this metadata. + ''', + a_legacy=LegacyDefinition(name='mapping_section_basis_set_cell_dependent')) + + number_of_basis_functions = Quantity( + type=int, + shape=[], + description=''' + Stores the total number of basis functions in a section_basis_set section. + ''', + a_legacy=LegacyDefinition(name='number_of_basis_functions')) + + +class section_restricted_uri(MSection): + ''' + Restricted URIs on this calculation (Coverage: any info or files that are related with + this calculation can be subject to restriction) + ''' + + m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_restricted_uri')) + + number_of_restricted_uri = Quantity( + type=np.dtype(np.int32), + shape=[], + description=''' + The number of restricted uris in restricted_uri list. + ''', + a_legacy=LegacyDefinition(name='number_of_restricted_uri')) + + restricted_uri = Quantity( + type=str, + shape=['number_of_restricted_uri'], + description=''' + The list of nomad uri(s) identifying the restricted info/file corresponding to + this calculation + ''', + a_legacy=LegacyDefinition(name='restricted_uri')) + + restricted_uri_reason = Quantity( + type=str, + shape=[], + description=''' + The reason of restriction for the uri or file. The reason can be 'propriety + license', 'open-source redistribution restricted license', 'other license', or + 'author restricted'. + ''', + a_legacy=LegacyDefinition(name='restricted_uri_reason')) + + restricted_uri_issue_authority = Quantity( + type=str, + shape=[], + description=''' + The issue authority is the restriction owner for the uri or file. This can be + license owner such as 'VASP' or 'AMBER', 'NOMAD', or the author of the uri. For + example the repository user name of the author. + ''', + a_legacy=LegacyDefinition(name='restricted_uri_issue_authority')) + + restricted_uri_end_date = Quantity( + type=str, + shape=[], + description=''' + The deadline date of the restriction for the uri or file. The end date can be in + date format string for those restrictions set by authors or NOMAD otherwise it is + set to 'unlimited' for the restriction related to license. + ''', + a_legacy=LegacyDefinition(name='restricted_uri_end_date')) + + restricted_uri_restriction = Quantity( + type=str, + shape=[], + description=''' + The type of restriction for the ur