├── .github └── workflows │ ├── publish-to-test-pypi.yml │ └── test.yml ├── .gitignore ├── LICENSE ├── README.md ├── data ├── GAMESS_CAS.log ├── chbrclf.log ├── crystal23_mgo_lda.d12 ├── crystal23_mgo_lda.out ├── diamond.cif ├── diamond_k_grid.chk ├── diamond_single_k.chk ├── h2o.json ├── methane_sphe.hdf5 ├── multistate_gamess.log ├── thiophene.g09.out ├── thiophene.gms.out ├── water.chk └── water.xyz ├── examples └── README.org ├── pyproject.toml ├── requirements.txt ├── setup.cfg ├── src ├── run_valgrind.sh └── trexio_tools │ ├── __init__.py │ ├── converters │ ├── __init__.py │ ├── cart_sphe.py │ ├── convert_back_end.py │ ├── convert_from.py │ ├── convert_to.py │ ├── crystal_to_trexio.py │ ├── orca_to_trexio.py │ └── pyscf_to_trexio.py │ ├── group_tools │ ├── __init__.py │ ├── ao.py │ ├── basis.py │ ├── check_basis.py │ ├── check_mos.py │ ├── determinant.py │ ├── mo.py │ ├── nao.py │ └── nucleus.py │ └── trexio_run.py └── utilities └── to_gamess_normalization.py /.github/workflows/publish-to-test-pypi.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [ master ] 4 | release: 5 | types: 6 | - published 7 | 8 | name: Publish Python distributions to PyPI 9 | jobs: 10 | 11 | get_commit_message: 12 | name: Get commit message 13 | runs-on: ubuntu-latest 14 | outputs: 15 | message: ${{ steps.commit_message.outputs.message }} 16 | steps: 17 | - name: Checkout the repo 18 | uses: actions/checkout@v3 19 | # Gets the correct commit message for pull request 20 | with: 21 | ref: ${{ github.event.pull_request.head.sha }} 22 | - name: Get commit message 23 | id: commit_message 24 | run: | 25 | set -xe 26 | COMMIT_MSG=$(git log --no-merges -1 --oneline) 27 | echo "::set-output name=message::$COMMIT_MSG" 28 | 29 | 30 | build-n-publish: 31 | name: Build and publish Python 🐍 distributions 📦 to PyPI 32 | needs: get_commit_message 33 | # The Python package will be published to PyPI only if commit contains 34 | # [pypi release] trigger in its message or if there is a release on GitHub. 35 | # NOTE: do not forget to update the `version` parameter in `setup.cfg` before pushing ! 36 | if: >- 37 | contains(needs.get_commit_message.outputs.message, '[pypi release]') || 38 | github.event_name == 'release' 39 | runs-on: ubuntu-latest 40 | 41 | steps: 42 | - uses: actions/checkout@v3 43 | 44 | - name: Set up Python 3.10 45 | uses: actions/setup-python@v4 46 | with: 47 | python-version: '3.10' 48 | 49 | - name: Install PyPA build and setuptools 50 | run: python -m pip install -U setuptools build --user 51 | 52 | - name: Build a binary wheel and a source tarball 53 | run: python -m build --sdist --wheel --outdir dist/ . 54 | 55 | - name: List all produced packages and wheels 56 | run: ls -sh -w 1 57 | working-directory: dist 58 | 59 | #- name: Publish distribution 📦 to Test PyPI 60 | # uses: pypa/gh-action-pypi-publish@master 61 | # with: 62 | # password: ${{ secrets.TEST_PYPI_API_TOKEN }} 63 | # repository_url: https://test.pypi.org/legacy/ 64 | 65 | - name: Publish distribution 📦 to PyPI 66 | uses: pypa/gh-action-pypi-publish@release/v1 67 | with: 68 | password: ${{ secrets.PYPI_API_TOKEN }} 69 | 70 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: TOOLS CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | 10 | jobs: 11 | 12 | test_tools: 13 | 14 | runs-on: ubuntu-latest 15 | name: x86 Ubuntu latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - name: create a virtual environment 21 | run: | 22 | python3 -m venv trexio_tools 23 | source trexio_tools/bin/activate 24 | 25 | - name: install dependencies 26 | run: pip install -r requirements.txt 27 | 28 | - name: install trexio_tools 29 | run: pip install . 30 | 31 | - name: check installation 32 | run: trexio --help 33 | 34 | - name: run tests 35 | run: | 36 | # benchmark the converters from external codes 37 | echo "== Starting conversion ==" 38 | trexio convert-from -t gaussian -i data/chbrclf.log -b hdf5 trexio_gaussi.h5 39 | trexio convert-from -t gamess -i data/GAMESS_CAS.log -b hdf5 trexio_gamess.h5 40 | trexio convert-from -t gamess -i data/multistate_gamess.log -b hdf5 multistate_gamess.h5 41 | trexio convert-from -t pyscf -i data/water.chk -b hdf5 trexio_pyscf_h2o_sph.h5 42 | trexio convert-from -t pyscf -i data/diamond_single_k.chk -b hdf5 trexio_pyscf_1k.h5 43 | trexio convert-from -t pyscf -i data/diamond_k_grid.chk -b hdf5 trexio_pyscf_Nk.h5 44 | trexio convert-from -t crystal -i data/crystal23_mgo_lda.out -m 1 -b hdf5 crystal.hdf5 45 | trexio convert-from -t orca -i data/h2o.json -b hdf5 trexio_orca_h2o_sph.h5 46 | trexio convert-to -t cartesian -o trexio_orca_h2o.h5 trexio_orca_h2o_sph.h5 47 | trexio convert-to -t cartesian -o trexio_pyscf_h2o.h5 trexio_pyscf_h2o_sph.h5 48 | echo "== Done conversion ==" 49 | # dummy checks for overwriting 50 | trexio convert-from -t gaussian -i data/chbrclf.log -b hdf5 trexio_gaussi.h5 || echo "Failure as it should" 51 | trexio convert-from -t gaussian -i data/chbrclf.log -b hdf5 -w trexio_gaussi.h5 && echo "Success as it should" 52 | echo "=== Check TREXIO file converted from GAMESS ===" 53 | trexio check-mos -n 50 trexio_gamess.h5 > mos-res 54 | grep "Norm of the error" < mos-res | grep -Eo "([0-9]+\.[0-9]*|\.?[0-9]+)([eE][+-][0-9]+)?" > error-res 55 | cat error-res 56 | python -c 'with open("error-res") as f: error = f.readline().strip(); assert float(error) < 0.12' 57 | echo "=== Check TREXIO file converted from GAMESS multistate calculation (State 1 of 2) ===" 58 | trexio check-mos -n 50 multistate_gamess.h5 > mos-res 59 | grep "Norm of the error" < mos-res | grep -Eo "([0-9]+\.[0-9]*|\.?[0-9]+)([eE][+-][0-9]+)?" > error-res 60 | python -c 'with open("error-res") as f: error = f.readline().strip(); assert float(error) < 1.0' 61 | echo "=== Check TREXIO file converted from GAMESS multistate calculation (State 2 of 2) ===" 62 | trexio check-mos -n 50 multistate_gamess_state_1.h5 > mos-res 63 | grep "Norm of the error" < mos-res | grep -Eo "([0-9]+\.[0-9]*|\.?[0-9]+)([eE][+-][0-9]+)?" > error-res 64 | python -c 'with open("error-res") as f: error = f.readline().strip(); assert float(error) < 1.0' 65 | echo "=== Check TREXIO file converted from PySCF ===" 66 | trexio check-mos -n 100 trexio_pyscf_h2o.h5 > mos-res 67 | grep "Norm of the error" < mos-res | grep -Eo "([0-9]+\.[0-9]*|\.?[0-9]+)([eE][+-][0-9]+)?" > error-res 68 | cat error-res 69 | python -c 'with open("error-res") as f: error = f.readline().strip(); assert float(error) < 0.00018' 70 | echo "=== Check TREXIO file converted from ORCA ===" 71 | trexio check-mos -n 100 trexio_orca_h2o.h5 > mos-res 72 | grep "Norm of the error" < mos-res | grep -Eo "([0-9]+\.[0-9]*|\.?[0-9]+)([eE][+-][0-9]+)?" > error-res 73 | cat error-res 74 | python -c 'with open("error-res") as f: error = f.readline().strip(); assert float(error) < 0.08' 75 | # benchmark helper converters 76 | trexio convert-to -t molden -o trexio_molden.h5 trexio_gamess.h5 77 | echo "=== Check normalization in spherical file ===" 78 | trexio check-mos -n 100 data/methane_sphe.hdf5 > mos-res 79 | grep "Norm of the error" < mos-res | grep -Eo "([0-9]+\.[0-9]*|\.?[0-9]+)([eE][+-][0-9]+)?" > error-res 80 | cat error-res 81 | python -c 'with open("error-res") as f: error = f.readline().strip(); assert float(error) < 0.0017' 82 | echo "=== Check normalization after transformation into cartesian file ===" 83 | trexio convert-to -t cartesian data/methane_sphe.hdf5 -o methane_cart.hdf5 84 | trexio check-mos -n 100 methane_cart.hdf5 > mos-res 85 | grep "Norm of the error" < mos-res | grep -Eo "([0-9]+\.[0-9]*|\.?[0-9]+)([eE][+-][0-9]+)?" > error-res 86 | cat error-res 87 | python -c 'with open("error-res") as f: error = f.readline().strip(); assert float(error) < 0.0017' 88 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # TREXIO files 2 | *.dir/ 3 | *.h5 4 | 5 | kp_info.dat 6 | 7 | # Byte-compiled / optimized / DLL files 8 | __pycache__/ 9 | *.py[cod] 10 | *$py.class 11 | 12 | # C extensions 13 | *.so 14 | 15 | # Distribution / packaging 16 | .Python 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | downloads/ 21 | eggs/ 22 | .eggs/ 23 | lib/ 24 | lib64/ 25 | parts/ 26 | sdist/ 27 | var/ 28 | wheels/ 29 | pip-wheel-metadata/ 30 | share/python-wheels/ 31 | *.egg-info/ 32 | .installed.cfg 33 | *.egg 34 | MANIFEST 35 | 36 | # PyInstaller 37 | # Usually these files are written by a python script from a template 38 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 39 | *.manifest 40 | *.spec 41 | 42 | # Installer logs 43 | pip-log.txt 44 | pip-delete-this-directory.txt 45 | 46 | # Unit test / coverage reports 47 | htmlcov/ 48 | .tox/ 49 | .nox/ 50 | .coverage 51 | .coverage.* 52 | .cache 53 | nosetests.xml 54 | coverage.xml 55 | *.cover 56 | *.py,cover 57 | .hypothesis/ 58 | .pytest_cache/ 59 | 60 | # Translations 61 | *.mo 62 | *.pot 63 | 64 | # Django stuff: 65 | *.log 66 | local_settings.py 67 | db.sqlite3 68 | db.sqlite3-journal 69 | 70 | # Flask stuff: 71 | instance/ 72 | .webassets-cache 73 | 74 | # Scrapy stuff: 75 | .scrapy 76 | 77 | # Sphinx documentation 78 | docs/_build/ 79 | 80 | # PyBuilder 81 | target/ 82 | 83 | # Jupyter Notebook 84 | .ipynb_checkpoints 85 | 86 | # IPython 87 | profile_default/ 88 | ipython_config.py 89 | 90 | # pyenv 91 | .python-version 92 | 93 | # pipenv 94 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 95 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 96 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 97 | # install all needed dependencies. 98 | #Pipfile.lock 99 | 100 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 101 | __pypackages__/ 102 | 103 | # Celery stuff 104 | celerybeat-schedule 105 | celerybeat.pid 106 | 107 | # SageMath parsed files 108 | *.sage.py 109 | 110 | # Environments 111 | .env 112 | .venv 113 | env/ 114 | venv/ 115 | ENV/ 116 | env.bak/ 117 | venv.bak/ 118 | 119 | # Spyder project settings 120 | .spyderproject 121 | .spyproject 122 | 123 | # Rope project settings 124 | .ropeproject 125 | 126 | # mkdocs documentation 127 | /site 128 | 129 | # mypy 130 | .mypy_cache/ 131 | .dmypy.json 132 | dmypy.json 133 | 134 | # Pyre type checker 135 | .pyre/ 136 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, TREX Center of Excellence 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TREXIO tools 2 | 3 | [![PyPI version](https://badge.fury.io/py/trexio-tools.svg)](https://badge.fury.io/py/trexio-tools) 4 | 5 | Set of tools for TREXIO files. 6 | 7 | 8 | ## Requirements 9 | 10 | - python3 (>=3.6) 11 | - trexio (>=1.0.0) [Python API] 12 | - numpy (>=1.17.3) 13 | - resultsFile [for GAMESS/GAU$$IAN conversion] 14 | - docopt [for CLI] 15 | - pyscf [only if you use the pyscf->trexio converter] 16 | 17 | **Deprecation note:** the pyscf--->trexio converter in this repository is no longer maintained. Please install the [pyscf-forge](https://github.com/pyscf/pyscf-forge) plugin for the latest and the most complete pyscf<--->trexio interface (including multi-reference wave function I/O). 18 | 19 | 20 | ## Installation 21 | 22 | ### Installation via PyPI, periodically updated 23 | 24 | `pip install trexio-tools` 25 | 26 | ### Installation from source code 27 | 28 | `pip install git+https://github.com/TREX-CoE/trexio_tools` 29 | 30 | 31 | ## Instructions for users 32 | 33 | After installation, `trexio-tools` provides an entry point, which can be accessed via CLI: 34 | 35 | `trexio --help` 36 | 37 | This will list all currently supported command line arguments. For example, 38 | 39 | `trexio convert-from -t gamess -i data/GAMESS_CAS.log -b hdf5 trexio_cas.hdf5` 40 | 41 | converts data from the `GAMESS_CAS.log` output file of the GAMESS code 42 | (note also `-t gamess` argument) into the TREXIO file called `trexio_cas.hdf5` 43 | using `-b hdf5` back end of TREXIO. 44 | 45 | and, 46 | 47 | `trexio convert-from -t orca -i data/h2o.json -b hdf5 trexio_orca.hdf5` 48 | 49 | Note that since ORCA AOs and MOs are in spherical coordinates, one needs to convert 50 | these to cartesian to be able to use `trexio` functions. 51 | 52 | `trexio convert-to -t cartesian -o trexio_orca_cart.hdf5 trexio_orca.hdf5` 53 | 54 | converts data from the `h2o.json` output file of the ORCA code 55 | into the TREXIO file called `trexio_orca.hdf5` using `-b hdf5` back end of TREXIO 56 | followed by converting the spherical AOs and MOs to cartesian coordinates. 57 | 58 | -------------------------------------------------------------------------------- /data/crystal23_mgo_lda.d12: -------------------------------------------------------------------------------- 1 | MGO BULK 2 | CRYSTAL 3 | 0 0 0 4 | 225 5 | 4.217 6 | 2 7 | 212 0. 0. 0. 8 | 208 0.5 0.5 0.5 9 | SUPERCON 10 | 1. 0. 0. 11 | 0. 1. 0. 12 | 0. 0. 1. 13 | SYMMREMO 14 | END 15 | 212 3 16 | INPUT 17 | 2 3 2 2 0 0 0 18 | 6.048538 2.0000000 -1 19 | 2.796989 12.097075 1 20 | 2.547408 -17.108313 0 21 | 5.936017 6.4286310 0 22 | 1.592891 14.195491 0 23 | 1.583969 3.3150690 0 24 | 1.077297 4.4030250 0 25 | 0 0 8 2.0 1 26 | 51.711283 0.000083 27 | 22.892200 -0.000504 28 | 10.134207 0.002477 29 | 4.4863380 -0.035477 30 | 1.9860680 0.300679 31 | 0.8792180 -1.149472 32 | 0.3892230 -0.471531 33 | 0.1723060 1.517235 34 | 0 2 8 0.0 1 35 | 13.152061 0.004595 36 | 6.9794760 -0.011998 37 | 3.7038360 0.147547 38 | 1.9655350 0.189666 39 | 1.0430610 -0.177158 40 | 0.5535270 -1.874453 41 | 0.2937430 3.963334 42 | 0.1558820 -1.689637 43 | 0 3 1 0.0 1 44 | 0.1452900 1.000000 45 | 208 5 46 | INPUT 47 | 6 3 1 0 0 0 0 48 | 12.30997 6.000000 -1 49 | 14.76962 73.85984 1 50 | 13.71419 -47.87600 0 51 | 13.65512 85.86406 0 52 | 0 0 9 2.0 1 53 | 54.775216 -0.001244 54 | 25.616801 0.010733 55 | 11.980245 0.001889 56 | 6.9923170 -0.174254 57 | 2.6202770 0.001762 58 | 1.2254290 0.316185 59 | 0.5777970 0.451202 60 | 0.2680220 0.312153 61 | 0.1253460 0.051117 62 | 0 0 1 0.0 1 63 | 0.2585510 1.000000 64 | 0 2 8 4.0 1 65 | 22.217266 0.010704 66 | 10.747550 0.037402 67 | 5.3157850 0.082032 68 | 2.6607610 0.166071 69 | 1.3318160 0.242704 70 | 0.6786260 0.286965 71 | 0.3336730 0.269793 72 | 0.1670170 0.149638 73 | 0 2 1 0.0 1 74 | 0.2678650 1.000000 75 | 0 3 1 0.0 1 76 | 1.2327530 1.000000 77 | 99 0 78 | END 79 | DFT 80 | EXCHANGE 81 | LDA 82 | CORRELAT 83 | PZ 84 | END 85 | TOLINTEG 86 | 7 7 7 7 14 87 | TOLDEE 88 | 7 89 | SHRINK 90 | 4 4 91 | NODIIS 92 | NODIRECT 93 | PRINTOUT 94 | KWEIGHTS 95 | END 96 | SETPRINT 97 | 1 98 | 67 -536 99 | END 100 | END 101 | -------------------------------------------------------------------------------- /data/diamond.cif: -------------------------------------------------------------------------------- 1 | data_image0 2 | _chemical_formula_structural C8 3 | _chemical_formula_sum "C8" 4 | _cell_length_a 3.567 5 | _cell_length_b 3.567 6 | _cell_length_c 3.567 7 | _cell_angle_alpha 90 8 | _cell_angle_beta 90 9 | _cell_angle_gamma 90 10 | 11 | _space_group_name_H-M_alt "P 1" 12 | _space_group_IT_number 1 13 | 14 | loop_ 15 | _space_group_symop_operation_xyz 16 | 'x, y, z' 17 | 18 | loop_ 19 | _atom_site_type_symbol 20 | _atom_site_label 21 | _atom_site_symmetry_multiplicity 22 | _atom_site_fract_x 23 | _atom_site_fract_y 24 | _atom_site_fract_z 25 | _atom_site_occupancy 26 | C C1 1.0 0.12500 0.12500 0.12500 1.0000 27 | C C2 1.0 0.62500 0.12500 0.62500 1.0000 28 | C C3 1.0 0.12500 0.62500 0.62500 1.0000 29 | C C4 1.0 0.62500 0.62500 0.12500 1.0000 30 | C C5 1.0 0.87500 0.37500 0.37500 1.0000 31 | C C6 1.0 0.87500 0.87500 0.87500 1.0000 32 | C C7 1.0 0.37500 0.37500 0.87500 1.0000 33 | C C8 1.0 0.37500 0.87500 0.37500 1.0000 34 | -------------------------------------------------------------------------------- /data/diamond_k_grid.chk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TREX-CoE/trexio_tools/9e38a2961b8282625039974aa2af1963657c1a88/data/diamond_k_grid.chk -------------------------------------------------------------------------------- /data/diamond_single_k.chk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TREX-CoE/trexio_tools/9e38a2961b8282625039974aa2af1963657c1a88/data/diamond_single_k.chk -------------------------------------------------------------------------------- /data/methane_sphe.hdf5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TREX-CoE/trexio_tools/9e38a2961b8282625039974aa2af1963657c1a88/data/methane_sphe.hdf5 -------------------------------------------------------------------------------- /data/water.chk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TREX-CoE/trexio_tools/9e38a2961b8282625039974aa2af1963657c1a88/data/water.chk -------------------------------------------------------------------------------- /data/water.xyz: -------------------------------------------------------------------------------- 1 | 3 2 | # Bonded water-methane complex 8 atoms 3 | O 5.000000 7.147077 7.650971 4 | H 4.068066 6.942975 7.563761 5 | H 5.380237 6.896963 6.807984 6 | -------------------------------------------------------------------------------- /examples/README.org: -------------------------------------------------------------------------------- 1 | #+TITLE: TREXIO example files 2 | 3 | This notebook generates some example files using quantum package. 4 | The produced files are archived on the git repository, so the text 5 | interface is used. 6 | 7 | * Water 8 | 9 | #+BEGIN_SRC bash 10 | cat << EOF > h2o.xyz 11 | 3 12 | Water 13 | O 0. 0. 0. 14 | H -0.756950272703377558 0. -0.585882234512562827 15 | H 0.756950272703377558 0. -0.585882234512562827 16 | 17 | EOF 18 | #+END_SRC 19 | 20 | 21 | #+BEGIN_SRC bash :results drawer 22 | source ~/qp2/quantum_package.rc 23 | rm -rf h2o 24 | qp create_ezfio -b aug-cc-pvdz h2o.xyz -o h2o 25 | qp set_file h2o 26 | qp run scf 27 | #+END_SRC 28 | 29 | 30 | #+BEGIN_SRC bash :results drawer 31 | source ~/qp2/quantum_package.rc 32 | qp set_frozen_core 33 | qp run fci 34 | #+END_SRC 35 | 36 | 37 | #+BEGIN_SRC bash :results drawer 38 | source ~/qp2/quantum_package.rc 39 | qp set_file h2o 40 | qp set trexio backend 1 41 | qp set trexio trexio_file h2o.trexio 42 | qp set trexio export_ao_ints 1 43 | qp set trexio export_mo_ints 1 44 | qp set trexio export_rdm 1 45 | qp run export_trexio 46 | #+END_SRC 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "setuptools>=51", 4 | "wheel" 5 | ] 6 | build-backend = "setuptools.build_meta" 7 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | trexio>=1.2.0 2 | resultsFile>=2.4 3 | scipy>=0.12.0 4 | docopt 5 | 6 | # NOTE: only install pyscf if you use the pyscf->trexio converter ! 7 | # It is quite a heavy package with a lot of functionalities which 8 | # you may not need 9 | 10 | pyscf==2.3.0 11 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = trexio-tools 3 | version = 0.8.0 4 | author = TREX-CoE 5 | author_email = evgenyp@qubit-pharmaceuticals.com 6 | description = Set of tools for TREXIO files 7 | long_description = file: README.md 8 | long_description_content_type = text/markdown 9 | url = https://github.com/TREX-CoE/trexio_tools 10 | project_urls = 11 | Bug Tracker = https://github.com/TREX-CoE/trexio_tools/issues 12 | license = BSD 3-Clause License 13 | license_file = LICENSE 14 | classifiers = 15 | Programming Language :: Python :: 3 16 | License :: OSI Approved :: BSD License 17 | Operating System :: OS Independent 18 | 19 | [options] 20 | zip_safe = False 21 | package_dir = 22 | = src 23 | packages = find: 24 | python_requires = >=3.6 25 | install_requires = 26 | docopt 27 | resultsFile>=2.4 28 | trexio>=1.2 29 | 30 | [options.entry_points] 31 | console_scripts = 32 | trexio = trexio_tools.trexio_run:main 33 | 34 | [options.packages.find] 35 | where = src 36 | -------------------------------------------------------------------------------- /src/run_valgrind.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export PYTHONMALLOC=malloc 4 | 5 | valgrind --tool=memcheck \ 6 | --dsymutil=yes \ 7 | --track-origins=yes \ 8 | --show-leak-kinds=all \ 9 | --trace-children=yes \ 10 | python trexio_run.py check-basis ./h2.ezfio.h5 11 | -------------------------------------------------------------------------------- /src/trexio_tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TREX-CoE/trexio_tools/9e38a2961b8282625039974aa2af1963657c1a88/src/trexio_tools/__init__.py -------------------------------------------------------------------------------- /src/trexio_tools/converters/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TREX-CoE/trexio_tools/9e38a2961b8282625039974aa2af1963657c1a88/src/trexio_tools/converters/__init__.py -------------------------------------------------------------------------------- /src/trexio_tools/converters/cart_sphe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | [ Cartesian x Spherical ] conversion matrices 4 | """ 5 | 6 | import numpy as np 7 | 8 | def cart_sphe(n): 9 | """ Matrices have dimension ( N_cartesian, N_sperical ) """ 10 | if n == 0: 11 | result = np.array([ 12 | [1.0], 13 | ]) 14 | return result 15 | 16 | if n == 1: 17 | result = np.array([ 18 | [0, 0, 1.0], 19 | [1.0, 0, 0], 20 | [0, 1.0, 0], 21 | ]).T 22 | return result 23 | 24 | if n == 2: 25 | result = np.array([ 26 | [-0.5, 0, 0, -0.5, 0, 1.0], 27 | [0, 0, 1.0, 0, 0, 0], 28 | [0, 0, 0, 0, 1.0, 0], 29 | [0.86602540378443864676, 0, 0, -0.86602540378443864676, 0, 0], 30 | [0, 1.0, 0, 0, 0, 0], 31 | ]).T 32 | return result 33 | 34 | if n == 3: 35 | result = np.array([ 36 | [0, 0, -0.67082039324993690892, 0, 0, 0, 0, -0.67082039324993690892, 0, 1.0], 37 | [-0.61237243569579452455, 0, 0, -0.27386127875258305673, 0, 1.0954451150103322269, 0, 0, 0, 0], 38 | [0, -0.27386127875258305673, 0, 0, 0, 0, -0.61237243569579452455, 0, 1.0954451150103322269, 0], 39 | [0, 0, 0.86602540378443864676, 0, 0, 0, 0, -0.86602540378443864676, 0, 0], 40 | [0, 0, 0, 0, 1.0, 0, 0, 0, 0, 0], 41 | [0.790569415042094833, 0, 0, -1.0606601717798212866, 0, 0, 0, 0, 0, 0], 42 | [0, 1.0606601717798212866, 0, 0, 0, 0, -0.790569415042094833, 0, 0, 0], 43 | ]).T 44 | return result 45 | 46 | if n == 4: 47 | result = np.array([ 48 | [0.375, 0, 0, 0.21957751641341996535, 0, -0.87831006565367986142, 0, 0, 0, 0, 0.375, 0, -0.87831006565367986142, 0, 1.0], 49 | [0, 0, -0.89642145700079522998, 0, 0, 0, 0, -0.40089186286863657703, 0, 1.19522860933439364, 0, 0, 0, 0, 0], 50 | [0, 0, 0, 0, -0.40089186286863657703, 0, 0, 0, 0, 0, 0, -0.89642145700079522998, 0, 1.19522860933439364, 0], 51 | [-0.5590169943749474241, 0, 0, 0, 0, 0.9819805060619657157, 0, 0, 0, 0, 0.5590169943749474241, 0, -0.9819805060619657157, 0, 0], 52 | [0, -0.42257712736425828875, 0, 0, 0, 0, -0.42257712736425828875, 0, 1.1338934190276816816, 0, 0, 0, 0, 0, 0], 53 | [0, 0, 0.790569415042094833, 0, 0, 0, 0, -1.0606601717798212866, 0, 0, 0, 0, 0, 0, 0], 54 | [0, 0, 0, 0, 1.0606601717798212866, 0, 0, 0, 0, 0, 0, -0.790569415042094833, 0, 0, 0], 55 | [0.73950997288745200532, 0, 0, -1.2990381056766579701, 0, 0, 0, 0, 0, 0, 0.73950997288745200532, 0, 0, 0, 0], 56 | [0, 1.1180339887498948482, 0, 0, 0, 0, -1.1180339887498948482, 0, 0, 0, 0, 0, 0, 0, 0], 57 | ]).T 58 | return result 59 | 60 | if n == 5: 61 | result = np.array([ 62 | [0, 0, 0.625, 0, 0, 0, 0, 0.36596252735569994226, 0, -1.0910894511799619063, 0, 0, 0, 0, 0, 0, 0.625, 0, -1.0910894511799619063, 0, 1.0], 63 | [0.48412291827592711065, 0, 0, 0.21128856368212914438, 0, -1.2677313820927748663, 0, 0, 0, 0, 0.16137430609197570355, 0, -0.56694670951384084082, 0, 1.2909944487358056284, 0, 0, 0, 0, 0, 0], 64 | [0, 0.16137430609197570355, 0, 0, 0, 0, 0.21128856368212914438, 0, -0.56694670951384084082, 0, 0, 0, 0, 0, 0, 0.48412291827592711065, 0, -1.2677313820927748663, 0, 1.2909944487358056284, 0], 65 | [0, 0, -0.85391256382996653193, 0, 0, 0, 0, 0, 0, 1.1180339887498948482, 0, 0, 0, 0, 0, 0, 0.85391256382996653193, 0, -1.1180339887498948482, 0, 0], 66 | [0, 0, 0, 0, -0.6454972243679028142, 0, 0, 0, 0, 0, 0, -0.6454972243679028142, 0, 1.2909944487358056284, 0, 0, 0, 0, 0, 0, 0], 67 | [-0.52291251658379721749, 0, 0, 0.22821773229381921394, 0, 0.91287092917527685576, 0, 0, 0, 0, 0.52291251658379721749, 0, -1.2247448713915890491, 0, 0, 0, 0, 0, 0, 0, 0], 68 | [0, -0.52291251658379721749, 0, 0, 0, 0, -0.22821773229381921394, 0, 1.2247448713915890491, 0, 0, 0, 0, 0, 0, 0.52291251658379721749, 0, -0.91287092917527685576, 0, 0, 0], 69 | [0, 0, 0.73950997288745200532, 0, 0, 0, 0, -1.2990381056766579701, 0, 0, 0, 0, 0, 0, 0, 0, 0.73950997288745200532, 0, 0, 0, 0], 70 | [0, 0, 0, 0, 1.1180339887498948482, 0, 0, 0, 0, 0, 0, -1.1180339887498948482, 0, 0, 0, 0, 0, 0, 0, 0, 0], 71 | [0.7015607600201140098, 0, 0, -1.5309310892394863114, 0, 0, 0, 0, 0, 0, 1.169267933366856683, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 72 | [0, 1.169267933366856683, 0, 0, 0, 0, -1.5309310892394863114, 0, 0, 0, 0, 0, 0, 0, 0, 0.7015607600201140098, 0, 0, 0, 0, 0], 73 | ]).T 74 | return result 75 | 76 | if n == 6: 77 | result = np.array([ 78 | [-0.3125, 0, 0, -0.16319780245846672329, 0, 0.97918681475080033975, 0, 0, 0, 0, -0.16319780245846672329, 0, 0.57335309036732873772, 0, -1.3055824196677337863, 0, 0, 0, 0, 0, 0, -0.3125, 0, 0.97918681475080033975, 0, -1.3055824196677337863, 0, 1.0], 79 | [0, 0, 0.86356159963469679725, 0, 0, 0, 0, 0.37688918072220452831, 0, -1.6854996561581052156, 0, 0, 0, 0, 0, 0, 0.28785386654489893242, 0, -0.75377836144440905662, 0, 1.3816985594155148756, 0, 0, 0, 0, 0, 0, 0], 80 | [0, 0, 0, 0, 0.28785386654489893242, 0, 0, 0, 0, 0, 0, 0.37688918072220452831, 0, -0.75377836144440905662, 0, 0, 0, 0, 0, 0, 0, 0, 0.86356159963469679725, 0, -1.6854996561581052156, 0, 1.3816985594155148756, 0], 81 | [0.45285552331841995543, 0, 0, 0.078832027985861408788, 0, -1.2613124477737825406, 0, 0, 0, 0, -0.078832027985861408788, 0, 0, 0, 1.2613124477737825406, 0, 0, 0, 0, 0, 0, -0.45285552331841995543, 0, 1.2613124477737825406, 0, -1.2613124477737825406, 0, 0], 82 | [0, 0.27308215547040717681, 0, 0, 0, 0, 0.26650089544451304287, 0, -0.95346258924559231545, 0, 0, 0, 0, 0, 0, 0.27308215547040717681, 0, -0.95346258924559231545, 0, 1.4564381625088382763, 0, 0, 0, 0, 0, 0, 0, 0], 83 | [0, 0, -0.81924646641122153043, 0, 0, 0, 0, 0.35754847096709711829, 0, 1.0660035817780521715, 0, 0, 0, 0, 0, 0, 0.81924646641122153043, 0, -1.4301938838683884732, 0, 0, 0, 0, 0, 0, 0, 0, 0], 84 | [0, 0, 0, 0, -0.81924646641122153043, 0, 0, 0, 0, 0, 0, -0.35754847096709711829, 0, 1.4301938838683884732, 0, 0, 0, 0, 0, 0, 0, 0, 0.81924646641122153043, 0, -1.0660035817780521715, 0, 0, 0], 85 | [-0.49607837082461073572, 0, 0, 0.43178079981734839863, 0, 0.86356159963469679725, 0, 0, 0, 0, 0.43178079981734839863, 0, -1.5169496905422946941, 0, 0, 0, 0, 0, 0, 0, 0, -0.49607837082461073572, 0, 0.86356159963469679725, 0, 0, 0, 0], 86 | [0, -0.59829302641309923139, 0, 0, 0, 0, 0, 0, 1.3055824196677337863, 0, 0, 0, 0, 0, 0, 0.59829302641309923139, 0, -1.3055824196677337863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 87 | [0, 0, 0.7015607600201140098, 0, 0, 0, 0, -1.5309310892394863114, 0, 0, 0, 0, 0, 0, 0, 0, 1.169267933366856683, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 88 | [0, 0, 0, 0, 1.169267933366856683, 0, 0, 0, 0, 0, 0, -1.5309310892394863114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7015607600201140098, 0, 0, 0, 0, 0], 89 | [0.67169328938139615748, 0, 0, -1.7539019000502850245, 0, 0, 0, 0, 0, 0, 1.7539019000502850245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.67169328938139615748, 0, 0, 0, 0, 0, 0], 90 | [0, 1.2151388809514737933, 0, 0, 0, 0, -1.9764235376052370825, 0, 0, 0, 0, 0, 0, 0, 0, 1.2151388809514737933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 91 | ]).T 92 | return result 93 | 94 | if n == 7: 95 | result = np.array([ 96 | [0, 0, -0.60670333962134435221, 0, 0, 0, 0, -0.31684048566533184861, 0, 1.4169537279434593918, 0, 0, 0, 0, 0, 0, -0.31684048566533184861, 0, 0.82968314787883083417, 0, -1.5208343311935928733, 0, 0, 0, 0, 0, 0, 0, 0, -0.60670333962134435221, 0, 1.4169537279434593918, 0, -1.5208343311935928733, 0, 1.0], 97 | [-0.41339864235384227977, 0, 0, -0.17963167078872714852, 0, 1.4370533663098171882, 0, 0, 0, 0, -0.13388954226515238921, 0, 0.62718150750531807803, 0, -2.1422326762424382273, 0, 0, 0, 0, 0, 0, -0.1146561540164598136, 0, 0.47901778876993906273, 0, -0.95803557753987812546, 0, 1.4675987714106856141, 0, 0, 0, 0, 0, 0, 0, 0], 98 | [0, -0.1146561540164598136, 0, 0, 0, 0, -0.13388954226515238921, 0, 0.47901778876993906273, 0, 0, 0, 0, 0, 0, -0.17963167078872714852, 0, 0.62718150750531807803, 0, -0.95803557753987812546, 0, 0, 0, 0, 0, 0, 0, 0, -0.41339864235384227977, 0, 1.4370533663098171882, 0, -2.1422326762424382273, 0, 1.4675987714106856141, 0], 99 | [0, 0, 0.84254721963085980365, 0, 0, 0, 0, 0.14666864502533059662, 0, -1.7491256557036030854, 0, 0, 0, 0, 0, 0, -0.14666864502533059662, 0, 0, 0, 1.4080189922431737275, 0, 0, 0, 0, 0, 0, 0, 0, -0.84254721963085980365, 0, 1.7491256557036030854, 0, -1.4080189922431737275, 0, 0], 100 | [0, 0, 0, 0, 0.50807509012231371428, 0, 0, 0, 0, 0, 0, 0.49583051751369852316, 0, -1.3222147133698627284, 0, 0, 0, 0, 0, 0, 0, 0, 0.50807509012231371428, 0, -1.3222147133698627284, 0, 1.6258402883914038857, 0, 0, 0, 0, 0, 0, 0, 0, 0], 101 | [0.42961647140211000062, 0, 0, -0.062226236090912312563, 0, -1.2445247218182462513, 0, 0, 0, 0, -0.23190348980538452414, 0, 0.54315511828342602619, 0, 1.2368186122953841287, 0, 0, 0, 0, 0, 0, -0.35746251148251142922, 0, 1.2445247218182462513, 0, -1.6593662957576616683, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 102 | [0, 0.35746251148251142922, 0, 0, 0, 0, 0.23190348980538452414, 0, -1.2445247218182462513, 0, 0, 0, 0, 0, 0, 0.062226236090912312563, 0, -0.54315511828342602619, 0, 1.6593662957576616683, 0, 0, 0, 0, 0, 0, 0, 0, -0.42961647140211000062, 0, 1.2445247218182462513, 0, -1.2368186122953841287, 0, 0, 0], 103 | [0, 0, -0.79037935147039945351, 0, 0, 0, 0, 0.6879369240987588816, 0, 1.025515817677958738, 0, 0, 0, 0, 0, 0, 0.6879369240987588816, 0, -1.8014417303072302517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.79037935147039945351, 0, 1.025515817677958738, 0, 0, 0, 0], 104 | [0, 0, 0, 0, -0.95323336395336381126, 0, 0, 0, 0, 0, 0, 0, 0, 1.5504341823651057024, 0, 0, 0, 0, 0, 0, 0, 0, 0.95323336395336381126, 0, -1.5504341823651057024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 105 | [-0.47495887979908323849, 0, 0, 0.61914323168888299344, 0, 0.82552430891851065792, 0, 0, 0, 0, 0.25637895441948968451, 0, -1.8014417303072302517, 0, 0, 0, 0, 0, 0, 0, 0, -0.65864945955866621126, 0, 1.3758738481975177632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 106 | [0, -0.65864945955866621126, 0, 0, 0, 0, 0.25637895441948968451, 0, 1.3758738481975177632, 0, 0, 0, 0, 0, 0, 0.61914323168888299344, 0, -1.8014417303072302517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.47495887979908323849, 0, 0.82552430891851065792, 0, 0, 0, 0, 0], 107 | [0, 0, 0.67169328938139615748, 0, 0, 0, 0, -1.7539019000502850245, 0, 0, 0, 0, 0, 0, 0, 0, 1.7539019000502850245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.67169328938139615748, 0, 0, 0, 0, 0, 0], 108 | [0, 0, 0, 0, 1.2151388809514737933, 0, 0, 0, 0, 0, 0, -1.9764235376052370825, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.2151388809514737933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 109 | [0.64725984928774934788, 0, 0, -1.96875, 0, 0, 0, 0, 0, 0, 2.4456993503903949804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.2566230789301937693, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 110 | [0, 1.2566230789301937693, 0, 0, 0, 0, -2.4456993503903949804, 0, 0, 0, 0, 0, 0, 0, 0, 1.96875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.64725984928774934788, 0, 0, 0, 0, 0, 0, 0], 111 | ]).T 112 | return result 113 | 114 | if n == 8: 115 | result = np.array([ 116 | [0.2734375, 0, 0, 0.13566299095694674896, 0, -1.0853039276555739917, 0, 0, 0, 0, 0.12099545906566282998, 0, -0.56678149117738375672, 0, 1.9359273450506052797, 0, 0, 0, 0, 0, 0, 0.13566299095694674896, 0, -0.56678149117738375672, 0, 1.1335629823547675134, 0, -1.7364862842489183867, 0, 0, 0, 0, 0, 0, 0, 0, 0.2734375, 0, -1.0853039276555739917, 0, 1.9359273450506052797, 0, -1.7364862842489183867, 0, 1.0], 117 | [0, 0, -0.84721510698287244363, 0, 0, 0, 0, -0.36813537731583001376, 0, 2.1951352762686132731, 0, 0, 0, 0, 0, 0, -0.27439190953357665914, 0, 0.95803557753987812546, 0, -2.6341623315223359277, 0, 0, 0, 0, 0, 0, 0, 0, -0.23497519304418891392, 0, 0.73171175875620442437, 0, -1.178033207410656044, 0, 1.5491933384829667541, 0, 0, 0, 0, 0, 0, 0, 0, 0], 118 | [0, 0, 0, 0, -0.23497519304418891392, 0, 0, 0, 0, 0, 0, -0.27439190953357665914, 0, 0.73171175875620442437, 0, 0, 0, 0, 0, 0, 0, 0, -0.36813537731583001376, 0, 0.95803557753987812546, 0, -1.178033207410656044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.84721510698287244363, 0, 2.1951352762686132731, 0, -2.6341623315223359277, 0, 1.5491933384829667541, 0], 119 | [-0.39218438743784791311, 0, 0, -0.0972889728117695298, 0, 1.459334592176542947, 0, 0, 0, 0, 0, 0, 0.25403754506115685714, 0, -2.3138757483972597747, 0, 0, 0, 0, 0, 0, 0.0972889728117695298, 0, -0.25403754506115685714, 0, 0, 0, 1.5566235649883124768, 0, 0, 0, 0, 0, 0, 0, 0, 0.39218438743784791311, 0, -1.459334592176542947, 0, 2.3138757483972597747, 0, -1.5566235649883124768, 0, 0], 120 | [0, -0.20252314682524563222, 0, 0, 0, 0, -0.1967766362666553471, 0, 0.8800118701519835797, 0, 0, 0, 0, 0, 0, -0.1967766362666553471, 0, 0.85880364827689588344, 0, -1.7491256557036030854, 0, 0, 0, 0, 0, 0, 0, 0, -0.20252314682524563222, 0, 0.8800118701519835797, 0, -1.7491256557036030854, 0, 1.7974340685458342478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 121 | [0, 0, 0.82265291131801144316, 0, 0, 0, 0, -0.11915417049417047641, 0, -1.7762455001837659611, 0, 0, 0, 0, 0, 0, -0.44406137504594149028, 0, 0.77521709118255285119, 0, 1.4209964001470127689, 0, 0, 0, 0, 0, 0, 0, 0, -0.68448859700003543819, 0, 1.7762455001837659611, 0, -1.9064667279067276225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 122 | [0, 0, 0, 0, 0.68448859700003543819, 0, 0, 0, 0, 0, 0, 0.44406137504594149028, 0, -1.7762455001837659611, 0, 0, 0, 0, 0, 0, 0, 0, 0.11915417049417047641, 0, -0.77521709118255285119, 0, 1.9064667279067276225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.82265291131801144316, 0, 1.7762455001837659611, 0, -1.4209964001470127689, 0, 0, 0], 123 | [0.41132645565900572158, 0, 0, -0.20407507102873838124, 0, -1.2244504261724302874, 0, 0, 0, 0, -0.3033516698106721761, 0, 1.0657473001102595767, 0, 1.2134066792426887044, 0, 0, 0, 0, 0, 0, -0.20407507102873838124, 0, 1.0657473001102595767, 0, -2.1314946002205191534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.41132645565900572158, 0, -1.2244504261724302874, 0, 1.2134066792426887044, 0, 0, 0, 0], 124 | [0, 0.42481613669916071115, 0, 0, 0, 0, 0.13758738481975177632, 0, -1.4767427774562605828, 0, 0, 0, 0, 0, 0, -0.13758738481975177632, 0, 0, 0, 1.8344984642633570176, 0, 0, 0, 0, 0, 0, 0, 0, -0.42481613669916071115, 0, 1.4767427774562605828, 0, -1.8344984642633570176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 125 | [0, 0, -0.76584818175667166625, 0, 0, 0, 0, 0.99833846339806020718, 0, 0.99215674164922147144, 0, 0, 0, 0, 0, 0, 0.41339864235384227977, 0, -2.1650635094610966169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.0620403417479017779, 0, 1.6535945694153691191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 126 | [0, 0, 0, 0, -1.0620403417479017779, 0, 0, 0, 0, 0, 0, 0.41339864235384227977, 0, 1.6535945694153691191, 0, 0, 0, 0, 0, 0, 0, 0, 0.99833846339806020718, 0, -2.1650635094610966169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.76584818175667166625, 0, 0.99215674164922147144, 0, 0, 0, 0, 0], 127 | [-0.45768182862115030664, 0, 0, 0.79475821795059156217, 0, 0.79475821795059156217, 0, 0, 0, 0, 0, 0, -2.0752447144854989366, 0, 0, 0, 0, 0, 0, 0, 0, -0.79475821795059156217, 0, 2.0752447144854989366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.45768182862115030664, 0, -0.79475821795059156217, 0, 0, 0, 0, 0, 0], 128 | [0, -0.70903764004458888811, 0, 0, 0, 0, 0.53582588123382020898, 0, 1.4377717134510610478, 0, 0, 0, 0, 0, 0, 0.53582588123382020898, 0, -2.338535866733713366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.70903764004458888811, 0, 1.4377717134510610478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 129 | [0, 0, 0.64725984928774934788, 0, 0, 0, 0, -1.96875, 0, 0, 0, 0, 0, 0, 0, 0, 2.4456993503903949804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.2566230789301937693, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 130 | [0, 0, 0, 0, 1.2566230789301937693, 0, 0, 0, 0, 0, 0, -2.4456993503903949804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.96875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.64725984928774934788, 0, 0, 0, 0, 0, 0, 0], 131 | [0.626706654240043952, 0, 0, -2.176535018670731151, 0, 0, 0, 0, 0, 0, 3.2353561313826025233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.176535018670731151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.626706654240043952, 0, 0, 0, 0, 0, 0, 0, 0], 132 | [0, 1.2945196985754986958, 0, 0, 0, 0, -2.9348392204684739765, 0, 0, 0, 0, 0, 0, 0, 0, 2.9348392204684739765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.2945196985754986958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 133 | ]).T 134 | return result 135 | 136 | if n == 9: 137 | result = np.array([ 138 | [0, 0, 0.59686501473785067702, 0, 0, 0, 0, 0.29612797475437320937, 0, -1.7657660842403202261, 0, 0, 0, 0, 0, 0, 0.26411138361943717788, 0, -0.92214126273187869253, 0, 2.5354692827465969076, 0, 0, 0, 0, 0, 0, 0, 0, 0.29612797475437320937, 0, -0.92214126273187869253, 0, 1.4846187947947014119, 0, -1.952374120367905548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.59686501473785067702, 0, -1.7657660842403202261, 0, 2.5354692827465969076, 0, -1.952374120367905548, 0, 1.0], 139 | [0.36685490255855924707, 0, 0, 0.15916400393009351387, 0, -1.5916400393009351387, 0, 0, 0, 0, 0.11811420148091719529, 0, -0.6916059470489090194, 0, 3.1497120394911252077, 0, 0, 0, 0, 0, 0, 0.098709324918124403125, 0, -0.51549263708149354579, 0, 1.3746470322173161221, 0, -3.1586983973799809, 0, 0, 0, 0, 0, 0, 0, 0, 0.088975383089683195547, 0, -0.44144152106008005653, 0, 1.0499040131637084026, 0, -1.4126128673922561809, 0, 1.62697843363992129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 140 | [0, 0.088975383089683195547, 0, 0, 0, 0, 0.098709324918124403125, 0, -0.44144152106008005653, 0, 0, 0, 0, 0, 0, 0.11811420148091719529, 0, -0.51549263708149354579, 0, 1.0499040131637084026, 0, 0, 0, 0, 0, 0, 0, 0, 0.15916400393009351387, 0, -0.6916059470489090194, 0, 1.3746470322173161221, 0, -1.4126128673922561809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.36685490255855924707, 0, -1.5916400393009351387, 0, 3.1497120394911252077, 0, -3.1586983973799809, 0, 1.62697843363992129, 0], 141 | [0, 0, -0.83466307816035426155, 0, 0, 0, 0, -0.2070544267420625878, 0, 2.3149388661875113029, 0, 0, 0, 0, 0, 0, 0, 0, 0.40297913150666282783, 0, -2.9546917977869539993, 0, 0, 0, 0, 0, 0, 0, 0, 0.2070544267420625878, 0, -0.40297913150666282783, 0, 0, 0, 1.7063893769835631924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.83466307816035426155, 0, -2.3149388661875113029, 0, 2.9546917977869539993, 0, -1.7063893769835631924, 0, 0], 142 | [0, 0, 0, 0, -0.43101816018790287844, 0, 0, 0, 0, 0, 0, -0.4187881980957120927, 0, 1.395960660319040309, 0, 0, 0, 0, 0, 0, 0, 0, -0.4187881980957120927, 0, 1.3623181102386339839, 0, -2.2335370565104644944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.43101816018790287844, 0, 1.395960660319040309, 0, -2.2335370565104644944, 0, 1.9703687322875560157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 143 | [-0.37548796377180986812, 0, 0, 0, 0, 1.4661859659554465543, 0, 0, 0, 0, 0.12089373945199884835, 0, -0.21236437647040795145, 0, -2.417874789039976967, 0, 0, 0, 0, 0, 0, 0.20206443016189559856, 0, -0.79143530297864839268, 0, 1.0552470706381978569, 0, 1.6165154412951647885, 0, 0, 0, 0, 0, 0, 0, 0, 0.27320762396104757397, 0, -1.2199404645272449631, 0, 2.417874789039976967, 0, -2.16878304804843549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 144 | [0, -0.27320762396104757397, 0, 0, 0, 0, -0.20206443016189559856, 0, 1.2199404645272449631, 0, 0, 0, 0, 0, 0, -0.12089373945199884835, 0, 0.79143530297864839268, 0, -2.417874789039976967, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.21236437647040795145, 0, -1.0552470706381978569, 0, 2.16878304804843549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.37548796377180986812, 0, -1.4661859659554465543, 0, 2.417874789039976967, 0, -1.6165154412951647885, 0, 0, 0], 145 | [0, 0, 0.80430146722719804411, 0, 0, 0, 0, -0.39904527606894581113, 0, -1.7845847267806657796, 0, 0, 0, 0, 0, 0, -0.59316922059788797031, 0, 1.5532816304615888184, 0, 1.4236061294349311288, 0, 0, 0, 0, 0, 0, 0, 0, -0.39904527606894581113, 0, 1.5532816304615888184, 0, -2.5007351860179508607, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.80430146722719804411, 0, -1.7845847267806657796, 0, 1.4236061294349311288, 0, 0, 0, 0], 146 | [0, 0, 0, 0, 0.83067898344030094085, 0, 0, 0, 0, 0, 0, 0.26903627024228973454, 0, -2.1522901619383178764, 0, 0, 0, 0, 0, 0, 0, 0, -0.26903627024228973454, 0, 0, 0, 2.1522901619383178764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.83067898344030094085, 0, 2.1522901619383178764, 0, -2.1522901619383178764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 147 | [0.39636409043643194293, 0, 0, -0.34393377440500167929, 0, -1.2037682104175058775, 0, 0, 0, 0, -0.29776858550677551679, 0, 1.5691988753163563388, 0, 1.1910743420271020672, 0, 0, 0, 0, 0, 0, 0, 0, 0.64978432507844251538, 0, -2.5991373003137700615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.48066206207978815025, 0, -1.6693261563207085231, 0, 1.9851239033785034453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 148 | [0, 0.48066206207978815025, 0, 0, 0, 0, 0, 0, -1.6693261563207085231, 0, 0, 0, 0, 0, 0, -0.29776858550677551679, 0, 0.64978432507844251538, 0, 1.9851239033785034453, 0, 0, 0, 0, 0, 0, 0, 0, -0.34393377440500167929, 0, 1.5691988753163563388, 0, -2.5991373003137700615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.39636409043643194293, 0, -1.2037682104175058775, 0, 1.1910743420271020672, 0, 0, 0, 0, 0], 149 | [0, 0, -0.74463846463549402274, 0, 0, 0, 0, 1.2930544805637086353, 0, 0.96378590571704436469, 0, 0, 0, 0, 0, 0, 0, 0, -2.5166038696554342464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.2930544805637086353, 0, 2.5166038696554342464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.74463846463549402274, 0, -0.96378590571704436469, 0, 0, 0, 0, 0, 0], 150 | [0, 0, 0, 0, -1.1535889489914915606, 0, 0, 0, 0, 0, 0, 0.87177715295353129935, 0, 1.7435543059070625987, 0, 0, 0, 0, 0, 0, 0, 0, 0.87177715295353129935, 0, -2.8358912905407192076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.1535889489914915606, 0, 1.7435543059070625987, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 151 | [-0.44314852502786805507, 0, 0, 0.96132412415957630049, 0, 0.76905929932766104039, 0, 0, 0, 0, -0.33291539937855436029, 0, -2.3392235702823930554, 0, 0, 0, 0, 0, 0, 0, 0, -0.83466307816035426155, 0, 2.9059238431784376645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.75235513151094117345, 0, -1.4930907048606177933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 152 | [0, -0.75235513151094117345, 0, 0, 0, 0, 0.83466307816035426155, 0, 1.4930907048606177933, 0, 0, 0, 0, 0, 0, 0.33291539937855436029, 0, -2.9059238431784376645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.96132412415957630049, 0, 2.3392235702823930554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.44314852502786805507, 0, -0.76905929932766104039, 0, 0, 0, 0, 0, 0, 0], 153 | [0, 0, 0.626706654240043952, 0, 0, 0, 0, -2.176535018670731151, 0, 0, 0, 0, 0, 0, 0, 0, 3.2353561313826025233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.176535018670731151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.626706654240043952, 0, 0, 0, 0, 0, 0, 0, 0], 154 | [0, 0, 0, 0, 1.2945196985754986958, 0, 0, 0, 0, 0, 0, -2.9348392204684739765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.9348392204684739765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.2945196985754986958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 155 | [0.60904939217552380708, 0, 0, -2.3781845426185916576, 0, 0, 0, 0, 0, 0, 4.1179360680974030877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.4414040330583097636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.3294455750836041652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 156 | [0, 1.3294455750836041652, 0, 0, 0, 0, -3.4414040330583097636, 0, 0, 0, 0, 0, 0, 0, 0, 4.1179360680974030877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.3781845426185916576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.60904939217552380708, 0, 0, 0, 0, 0, 0, 0, 0, 0], 157 | ]).T 158 | return result 159 | 160 | if n == 10: 161 | result = np.array([ 162 | [-0.24609375, 0, 0, -0.11858505372305812003, 0, 1.1858505372305812003, 0, 0, 0, 0, -0.10047931526668538772, 0, 0.58834662659146160065, 0, -2.6794484071116103391, 0, 0, 0, 0, 0, 0, -0.10047931526668538772, 0, 0.52473611020974468895, 0, -1.3992962938926525039, 0, 3.2153380885339324069, 0, 0, 0, 0, 0, 0, 0, 0, -0.11858505372305812003, 0, 0.58834662659146160065, 0, -1.3992962938926525039, 0, 1.8827092050926771221, 0, -2.1684124109359199092, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.24609375, 0, 1.1858505372305812003, 0, -2.6794484071116103391, 0, 3.2153380885339324069, 0, -2.1684124109359199092, 0, 1.0], 163 | [0, 0, 0.83740417939178506787, 0, 0, 0, 0, 0.36331694402943203347, 0, -2.7080046140909879357, 0, 0, 0, 0, 0, 0, 0.26961429512272912425, 0, -1.1766932531829232013, 0, 4.313828721963665988, 0, 0, 0, 0, 0, 0, 0, 0, 0.22531960362226453071, 0, -0.87705536759412901916, 0, 1.8827092050926771221, 0, -3.7138348993247834547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.20310034605682409518, 0, -0.75106534540754843571, 0, 1.437942907321221996, 0, -1.6608774584202607245, 0, 1.7013926184468014077, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 164 | [0, 0, 0, 0, 0.20310034605682409518, 0, 0, 0, 0, 0, 0, 0.22531960362226453071, 0, -0.75106534540754843571, 0, 0, 0, 0, 0, 0, 0, 0, 0.26961429512272912425, 0, -0.87705536759412901916, 0, 1.437942907321221996, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.36331694402943203347, 0, -1.1766932531829232013, 0, 1.8827092050926771221, 0, -1.6608774584202607245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.83740417939178506787, 0, -2.7080046140909879357, 0, 4.313828721963665988, 0, -3.7138348993247834547, 0, 1.7013926184468014077, 0], 165 | [0.35123682832287462164, 0, 0, 0.10155017302841204759, 0, -1.6248027684545927614, 0, 0, 0, 0, 0.028681781643235369086, 0, -0.40306396029015307011, 0, 3.4418137971882442903, 0, 0, 0, 0, 0, 0, -0.028681781643235369086, 0, 0, 0, 0.59914287805050916501, 0, -3.671268050334127243, 0, 0, 0, 0, 0, 0, 0, 0, -0.10155017302841204759, 0, 0.40306396029015307011, 0, -0.59914287805050916501, 0, 0, 0, 1.8569174496623917273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.35123682832287462164, 0, 1.6248027684545927614, 0, -3.4418137971882442903, 0, 3.671268050334127243, 0, -1.8569174496623917273, 0, 0], 166 | [0, 0.16115850946412159102, 0, 0, 0, 0, 0.15634671929121805204, 0, -0.83904454174617912686, 0, 0, 0, 0, 0, 0, 0.15566188586647886474, 0, -0.81523699977453260905, 0, 2.0754918115530515298, 0, 0, 0, 0, 0, 0, 0, 0, 0.15634671929121805204, 0, -0.81523699977453260905, 0, 2.0254726102987062665, 0, -2.7752177878403030036, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.16115850946412159102, 0, -0.83904454174617912686, 0, 2.0754918115530515298, 0, -2.7752177878403030036, 0, 2.144183578850990428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 167 | [0, 0, -0.82175038453908348563, 0, 0, 0, 0, 0, 0, 2.3916449176564030209, 0, 0, 0, 0, 0, 0, 0.26457433118527621615, 0, -0.34640911417109820836, 0, -3.1748919742233145938, 0, 0, 0, 0, 0, 0, 0, 0, 0.44221530170835956711, 0, -1.2909905455201021811, 0, 1.3856364566843928334, 0, 1.822205651547735635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.59791122941410075523, 0, -1.989968857687618052, 0, 3.1748919742233145938, 0, -2.4447454235070190498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 168 | [0, 0, 0, 0, -0.59791122941410075523, 0, 0, 0, 0, 0, 0, -0.44221530170835956711, 0, 1.989968857687618052, 0, 0, 0, 0, 0, 0, 0, 0, -0.26457433118527621615, 0, 1.2909905455201021811, 0, -3.1748919742233145938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.34640911417109820836, 0, -1.3856364566843928334, 0, 2.4447454235070190498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.82175038453908348563, 0, -2.3916449176564030209, 0, 3.1748919742233145938, 0, -1.822205651547735635, 0, 0, 0], 169 | [-0.36182925552841909469, 0, 0, 0.10461267311033710355, 0, 1.4645774235447194496, 0, 0, 0, 0, 0.20682726877269383945, 0, -0.72663388805886406695, 0, -2.4819272252723260733, 0, 0, 0, 0, 0, 0, 0.20682726877269383945, 0, -1.0801201840700893574, 0, 2.1602403681401787147, 0, 1.6546181501815507156, 0, 0, 0, 0, 0, 0, 0, 0, 0.10461267311033710355, 0, -0.72663388805886406695, 0, 2.1602403681401787147, 0, -2.9065355522354562678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.36182925552841909469, 0, 1.4645774235447194496, 0, -2.4819272252723260733, 0, 1.6546181501815507156, 0, 0, 0, 0], 170 | [0, -0.33203729677156513836, 0, 0, 0, 0, -0.16106174661573187074, 0, 1.5126090588320172805, 0, 0, 0, 0, 0, 0, 0, 0, 0.48989646739041700006, 0, -2.9933168593440682608, 0, 0, 0, 0, 0, 0, 0, 0, 0.16106174661573187074, 0, -0.48989646739041700006, 0, 0, 0, 2.5015475086594888326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.33203729677156513836, 0, -1.5126090588320172805, 0, 2.9933168593440682608, 0, -2.5015475086594888326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 171 | [0, 0, 0.78749559444256408387, 0, 0, 0, 0, -0.68332711933040086312, 0, -1.7826268713072013905, 0, 0, 0, 0, 0, 0, -0.59160618963182012549, 0, 2.3237829819361839259, 0, 1.4198548551163683012, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.96224753936416168989, 0, -3.0983773092482452346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.95497868105742931632, 0, -2.4720586882761771815, 0, 2.366424758527280502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 172 | [0, 0, 0, 0, 0.95497868105742931632, 0, 0, 0, 0, 0, 0, 0, 0, -2.4720586882761771815, 0, 0, 0, 0, 0, 0, 0, 0, -0.59160618963182012549, 0, 0.96224753936416168989, 0, 2.366424758527280502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.68332711933040086312, 0, 2.3237829819361839259, 0, -3.0983773092482452346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.78749559444256408387, 0, -1.7826268713072013905, 0, 1.4198548551163683012, 0, 0, 0, 0, 0], 173 | [0.38377788032373784791, 0, 0, -0.48082014860341125496, 0, -1.1835572888699353968, 0, 0, 0, 0, -0.21937344642519671472, 0, 2.0552309987454778474, 0, 1.1699917142677158118, 0, 0, 0, 0, 0, 0, 0.21937344642519671472, 0, 0, 0, -3.0550412266096884411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.48082014860341125496, 0, -2.0552309987454778474, 0, 3.0550412266096884411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.38377788032373784791, 0, 1.1835572888699353968, 0, -1.1699917142677158118, 0, 0, 0, 0, 0, 0], 174 | [0, 0.52826810434655366934, 0, 0, 0, 0, -0.17083177983260021578, 0, -1.8335590676302642873, 0, 0, 0, 0, 0, 0, -0.39686149677791432422, 0, 1.3856364566843928334, 0, 2.1165946494822097292, 0, 0, 0, 0, 0, 0, 0, 0, -0.17083177983260021578, 0, 1.3856364566843928334, 0, -3.4426414547202724829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.52826810434655366934, 0, -1.8335590676302642873, 0, 2.1165946494822097292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 175 | [0, 0, -0.72603506428855091706, 0, 0, 0, 0, 1.5749911888851281677, 0, 0.93914329661609541215, 0, 0, 0, 0, 0, 0, -0.54543395665202120543, 0, -2.8565627348081709585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.3674752986559612903, 0, 3.5485935872354305223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.2326255768086252285, 0, -1.8233003982079483871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 176 | [0, 0, 0, 0, -1.2326255768086252285, 0, 0, 0, 0, 0, 0, 1.3674752986559612903, 0, 1.8233003982079483871, 0, 0, 0, 0, 0, 0, 0, 0, 0.54543395665202120543, 0, -3.5485935872354305223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.5749911888851281677, 0, 2.8565627348081709585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.72603506428855091706, 0, -0.93914329661609541215, 0, 0, 0, 0, 0, 0, 0], 177 | [-0.43066295528485788256, 0, 0, 1.120625876604032342, 0, 0.74708391773602156131, 0, 0, 0, 0, -0.7385210685055943188, 0, -2.5946019526630973949, 0, 0, 0, 0, 0, 0, 0, 0, -0.7385210685055943188, 0, 3.8568004943805360605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.120625876604032342, 0, -2.5946019526630973949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.43066295528485788256, 0, 0.74708391773602156131, 0, 0, 0, 0, 0, 0, 0, 0], 178 | [0, -0.79040686350032478234, 0, 0, 0, 0, 1.1502109360323527426, 0, 1.5431699048592017869, 0, 0, 0, 0, 0, 0, 0, 0, -3.4985605592646392353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.1502109360323527426, 0, 3.4985605592646392353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.79040686350032478234, 0, -1.5431699048592017869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 179 | [0, 0, 0.60904939217552380708, 0, 0, 0, 0, -2.3781845426185916576, 0, 0, 0, 0, 0, 0, 0, 0, 4.1179360680974030877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.4414040330583097636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.3294455750836041652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 180 | [0, 0, 0, 0, 1.3294455750836041652, 0, 0, 0, 0, 0, 0, -3.4414040330583097636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.1179360680974030877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.3781845426185916576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.60904939217552380708, 0, 0, 0, 0, 0, 0, 0, 0, 0], 181 | [0.59362791713657322739, 0, 0, -2.5744602859939704749, 0, 0, 0, 0, 0, 0, 5.0899052063634372758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5.0899052063634372758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.5744602859939704749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.59362791713657322739, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 182 | [0, 1.361875842559399759, 0, 0, 0, 0, -3.9636409043643194293, 0, 0, 0, 0, 0, 0, 0, 0, 5.5247909851583978272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.9636409043643194293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.361875842559399759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 183 | ]).T 184 | return result 185 | 186 | raise TypeError("Angular momentum too large") 187 | 188 | data = {} 189 | for i in range(11): 190 | data[i] = cart_sphe(i) 191 | 192 | 193 | # What follows is generated by the utilities/to_gamess_normalization.py script 194 | 195 | normalization = {} 196 | normalization[0] = [1.0] 197 | normalization[1] = [1.0, 1.0, 1.0] 198 | normalization[2] = [1.0, 1.7320508075688772, 1.7320508075688772, 1.0, 1.7320508075688772, 1.0] 199 | normalization[3] = [1.0, 2.23606797749979, 2.23606797749979, 2.23606797749979, 3.872983346207417, 2.23606797749979, 1.0, 2.23606797749979, 2.23606797749979, 1.0] 200 | normalization[4] = [1.0, 2.6457513110645907, 2.6457513110645907, 3.4156502553198664, 5.916079783099616, 3.415650255319866, 2.6457513110645907, 5.916079783099616, 5.916079783099616, 2.6457513110645907, 1.0, 2.6457513110645907, 3.415650255319866, 2.6457513110645907, 1.0] 201 | normalization[5] = [0.9999999999999999, 3.0, 3.0000000000000004, 4.58257569495584, 7.937253933193773, 4.58257569495584, 4.58257569495584, 10.246950765959598, 10.246950765959598, 4.582575694955841, 3.0, 7.937253933193773, 10.246950765959598, 7.937253933193773, 3.0, 0.9999999999999999, 3.0000000000000004, 4.58257569495584, 4.582575694955841, 3.0, 1.0] 202 | normalization[6] = [1.0, 3.3166247903554003, 3.3166247903554003, 5.744562646538029, 9.949874371066201, 5.744562646538029, 6.797058187186571, 15.198684153570666, 15.198684153570664, 6.797058187186572, 5.744562646538029, 15.198684153570666, 19.621416870348583, 15.198684153570666, 5.744562646538029, 3.3166247903554003, 9.949874371066201, 15.198684153570664, 15.198684153570666, 9.9498743710662, 3.3166247903554003, 1.0, 3.3166247903554003, 5.744562646538029, 6.797058187186572, 5.744562646538029, 3.3166247903554003, 1.0] 203 | normalization[7] = [1.0000000000000002, 3.6055512754639896, 3.605551275463989, 6.904105059069327, 11.958260743101398, 6.904105059069326, 9.26282894152753, 20.712315177207984, 20.71231517720798, 9.26282894152753, 9.26282894152753, 24.507141816213494, 31.63858403911275, 24.507141816213494, 9.262828941527529, 6.904105059069327, 20.712315177207984, 31.63858403911275, 31.63858403911275, 20.71231517720798, 6.904105059069327, 3.6055512754639896, 11.958260743101398, 20.71231517720798, 24.507141816213494, 20.71231517720798, 11.958260743101398, 3.6055512754639896, 1.0000000000000002, 3.605551275463989, 6.904105059069326, 9.26282894152753, 9.262828941527529, 6.904105059069327, 3.6055512754639896, 1.0] 204 | normalization[8] = [1.0, 3.872983346207417, 3.872983346207417, 8.062257748298551, 13.964240043768942, 8.06225774829855, 11.958260743101398, 26.739483914241877, 26.739483914241877, 11.958260743101398, 13.55939315961975, 35.874782229304195, 46.31414470763765, 35.874782229304195, 13.55939315961975, 11.958260743101398, 35.874782229304195, 54.79963503528103, 54.79963503528103, 35.874782229304195, 11.958260743101398, 8.062257748298551, 26.739483914241877, 46.31414470763765, 54.79963503528103, 46.314144707637645, 26.739483914241877, 8.06225774829855, 3.872983346207417, 13.964240043768942, 26.739483914241877, 35.874782229304195, 35.874782229304195, 26.739483914241877, 13.96424004376894, 3.8729833462074166, 1.0, 3.872983346207417, 8.06225774829855, 11.958260743101398, 13.55939315961975, 11.958260743101398, 8.06225774829855, 3.8729833462074166, 1.0] 205 | normalization[9] = [1.0000000000000002, 4.1231056256176615, 4.1231056256176615, 9.219544457292889, 15.968719422671313, 9.219544457292889, 14.86606874731851, 33.24154027718933, 33.24154027718933, 14.866068747318508, 18.635603405463275, 49.30517214248421, 63.652703529910404, 49.30517214248421, 18.635603405463275, 18.635603405463275, 55.90681021638982, 85.39906322671229, 85.39906322671229, 55.90681021638983, 18.635603405463275, 14.86606874731851, 49.30517214248421, 85.39906322671229, 101.04553429023969, 85.3990632267123, 49.30517214248421, 14.866068747318508, 9.219544457292889, 33.24154027718933, 63.652703529910404, 85.39906322671229, 85.3990632267123, 63.65270352991039, 33.24154027718933, 9.219544457292887, 4.1231056256176615, 15.968719422671313, 33.24154027718933, 49.30517214248421, 55.90681021638983, 49.30517214248421, 33.24154027718933, 15.968719422671313, 4.1231056256176615, 1.0000000000000002, 4.1231056256176615, 9.219544457292889, 14.866068747318508, 18.635603405463275, 18.635603405463275, 14.866068747318508, 9.219544457292887, 4.1231056256176615, 1.0] 206 | normalization[10] = [1.0, 4.358898943540674, 4.358898943540674, 10.376254944182257, 17.97220075561143, 10.376254944182254, 17.972200755611432, 40.18706259482024, 40.18706259482024, 17.97220075561143, 24.491981195018568, 64.79969135728966, 83.6560418220545, 64.79969135728966, 24.491981195018564, 27.07690399877228, 81.23071199631686, 124.08196215942644, 124.08196215942641, 81.23071199631683, 27.07690399877228, 24.491981195018568, 81.23071199631686, 140.69572031261546, 166.47342130202045, 140.69572031261546, 81.23071199631684, 24.491981195018564, 17.972200755611432, 64.79969135728966, 124.08196215942644, 166.47342130202045, 166.47342130202045, 124.08196215942644, 64.79969135728965, 17.972200755611432, 10.376254944182257, 1.7763568394002502e+17, 83.6560418220545, 124.08196215942641, 140.69572031261546, 124.08196215942644, 83.65604182205452, 40.18706259482024, 10.376254944182254, 4.358898943540674, 17.97220075561143, 40.18706259482024, 64.79969135728966, 81.23071199631683, 81.23071199631684, 64.79969135728965, 40.18706259482024, 17.972200755611425, 4.358898943540674, 1.0, 4.358898943540674, 10.376254944182254, 17.97220075561143, 24.491981195018564, 27.07690399877228, 24.491981195018564, 17.972200755611432, 10.376254944182254, 4.358898943540674, 1.0] 207 | 208 | -------------------------------------------------------------------------------- /src/trexio_tools/converters/convert_back_end.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Convert a TREXIO file from one back end into another one. 4 | """ 5 | 6 | 7 | def generate_converter(json_filename: str) -> None: 8 | """ 9 | Function that generates the converter based on the trex.json configuration file. 10 | """ 11 | from os.path import join, dirname, abspath 12 | from json import load 13 | 14 | try: 15 | with open(json_filename, 'r') as f: 16 | config = load(f) 17 | except FileNotFoundError as e: 18 | raise Exception(f'File {json_filename} is not found.') from e 19 | 20 | fileDir = dirname(abspath(__file__)) 21 | output_file = join(fileDir, 'converter_generated.py') 22 | 23 | data_sparse = [] 24 | data_other = [] 25 | data_determinant = [] 26 | for group,attr in config.items(): 27 | for data,specs in attr.items(): 28 | name = f'{group}_{data}' 29 | if 'sparse' in specs[0]: 30 | data_sparse.append(name) 31 | elif 'determinant' in group: 32 | data_determinant.append(name) 33 | else: 34 | data_other.append(name) 35 | 36 | with open(output_file, 'w') as f_out: 37 | f_out.write('import trexio \n') 38 | f_out.write('def data_handler(trexio_file_from, trexio_file_to) -> None : \n') 39 | f_out.write(' buffer_size = 20000 \n') 40 | 41 | # Process the normal data first 42 | for attr in data_other: 43 | if 'package_version' in attr: 44 | continue 45 | block = f'\n\ 46 | if trexio.has_{attr}(trexio_file_from): \n\ 47 | data = trexio.read_{attr}(trexio_file_from) \n\ 48 | trexio.write_{attr}(trexio_file_to, data) \n\ 49 | ' 50 | f_out.write(block) 51 | 52 | # Now process the sparse data 53 | for attr in data_sparse: 54 | block = f'\n\ 55 | offset_file = 0 ; eof = False \n\ 56 | if trexio.has_{attr}(trexio_file_from): \n\ 57 | while(not eof): \n\ 58 | indices, values, read_size, eof = trexio.read_{attr}( \n\ 59 | trexio_file_from, offset_file, buffer_size \n\ 60 | ) \n\ 61 | trexio.write_{attr}( \n\ 62 | trexio_file_to, offset_file, read_size, indices, values \n\ 63 | ) \n\ 64 | offset_file += read_size \n\ 65 | ' 66 | f_out.write(block) 67 | 68 | # Finally process the determinant data 69 | for attr in data_determinant: 70 | if 'determinant_num' in attr: 71 | continue 72 | block = f'\n\ 73 | offset_file = 0 ; eof = False \n\ 74 | if trexio.has_{attr}(trexio_file_from): \n\ 75 | while(not eof): \n\ 76 | data, read_size, eof = trexio.read_{attr}( \n\ 77 | trexio_file_from, offset_file, buffer_size \n\ 78 | ) \n\ 79 | trexio.write_{attr}( \n\ 80 | trexio_file_to, offset_file, read_size, data \n\ 81 | ) \n\ 82 | offset_file += read_size \n\ 83 | ' 84 | f_out.write(block) 85 | 86 | 87 | def run_converter(filename_from, filename_to, back_end_to, back_end_from=None, overwrite=None): 88 | """The high-level converter function.""" 89 | 90 | import os 91 | import trexio 92 | 93 | try: 94 | # For proper python package 95 | from .converter_generated import data_handler 96 | except: 97 | try: 98 | # For argparse-based CLI 99 | from .converter_generated import data_handler 100 | except: 101 | raise ImportError('The generated (JSON-based) data_handler.py module cannot be imported.') 102 | 103 | if not os.path.exists(filename_from): 104 | raise FileNotFoundError(f'Input file {filename_from} not found.') 105 | 106 | if os.path.exists(filename_to): 107 | if overwrite: 108 | if '*' in filename_to: 109 | raise ValueError('Are you sure?') 110 | else: 111 | os.system(f'rm -rf -- {filename_to}') 112 | else: 113 | raise ValueError(f'Output file {filename_to} already exists. Consider using the `-w` argument.') 114 | 115 | if back_end_from is None: 116 | back_end_from = trexio.TREXIO_AUTO 117 | 118 | with trexio.File(filename_from, 'r', back_end_from) as trexio_file_from: 119 | with trexio.File(filename_to, 'w', back_end_to) as trexio_file_to: 120 | data_handler(trexio_file_from, trexio_file_to) 121 | 122 | 123 | def run(filename_from, filename_to, back_end_to, back_end_from=None, overwrite=None, json_filename='trex.json') -> None: 124 | """Interface to the upstream master script.""" 125 | 126 | generate_converter(json_filename) 127 | run_converter(filename_from, filename_to, back_end_to, back_end_from, overwrite) 128 | 129 | print(f'\n\ 130 | Conversion from {filename_from} to {filename_to} is finished. \n\ 131 | Note: conversion of the CI coefficients is performed only for ground state. \n\ 132 | ') 133 | 134 | 135 | if __name__ == '__main__': 136 | import argparse 137 | 138 | parser = argparse.ArgumentParser(description='Parser') 139 | parser.add_argument( 140 | '--json_file', 141 | type=str, 142 | nargs=1, 143 | default='trex.json', 144 | help='TREXIO configuration file (in JSON format).' 145 | ) 146 | parser.add_argument( 147 | '--file_from', 148 | type=str, 149 | nargs=1, 150 | required=True, 151 | help='Input TREXIO file name.' 152 | ) 153 | parser.add_argument( 154 | '--file_to', 155 | type=str, 156 | nargs=1, 157 | required=True, 158 | help='Output TREXIO file name.' 159 | ) 160 | parser.add_argument( 161 | '--back_end_to', 162 | type=int, 163 | nargs=1, 164 | required=True, 165 | help='Output TREXIO back end.' 166 | ) 167 | parser.add_argument( 168 | '--back_end_from', 169 | type=int, 170 | nargs=1, 171 | help='Input TREXIO back end.' 172 | ) 173 | parser.add_argument( 174 | '--overwrite', 175 | type=bool, 176 | nargs=1, 177 | default=True, 178 | help='Overwrite flag. Default: False.' 179 | ) 180 | 181 | args = parser.parse_args() 182 | 183 | json_filename = args.json_file[0] 184 | filename_from = args.file_from[0] 185 | filename_to = args.file_to[0] 186 | back_end_to = args.back_end_to[0] 187 | back_end_from = args.back_end_from[0] if isinstance(args.back_end_from, list) else args.back_end_from 188 | overwrite = args.overwrite[0] if isinstance(args.overwrite, list) else args.overwrite 189 | 190 | run(filename_from, filename_to, back_end_to, back_end_from, overwrite, json_filename) 191 | -------------------------------------------------------------------------------- /src/trexio_tools/converters/convert_from.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Convert output file from a given code/format into TREXIO 4 | """ 5 | 6 | import os 7 | from trexio_tools.group_tools import basis as trexio_basis 8 | from trexio_tools.group_tools import determinant as trexio_det 9 | 10 | from .pyscf_to_trexio import pyscf_to_trexio as run_pyscf 11 | from .orca_to_trexio import orca_to_trexio as run_orca 12 | from .crystal_to_trexio import crystal_to_trexio as run_crystal 13 | 14 | import trexio 15 | 16 | from ..trexio_run import remove_trexio_file 17 | 18 | try: 19 | from resultsFile import getFile, a0, get_lm 20 | import resultsFile 21 | except ImportError as exc: 22 | raise ImportError("resultsFile Python package is not installed.") from exc 23 | 24 | 25 | # Re-order AOs (xx,xy,xz,yy,yz,zz) or (d+0,+1,-1,-2,+2,-2,...) 26 | def f_sort(x): 27 | if '+' in x or '-' in x: 28 | l, m = get_lm(x) 29 | if m>=0: 30 | return 2*m 31 | else: 32 | return -2*m+1 33 | else: 34 | return x 35 | 36 | #def file_cleanup(trexio_filename, back_end): 37 | # if os.path.exists(trexio_filename): 38 | # print(f"TREXIO file {trexio_filename} already exists and will be removed before conversion.") 39 | # if back_end == trexio.TREXIO_HDF5: 40 | # os.remove(trexio_filename) 41 | # else: 42 | # raise NotImplementedError(f"Please remove the {trexio_filename} directory manually.") 43 | 44 | def run_resultsFile(trexio_file, filename_info, motype=None): 45 | 46 | filename = filename_info['filename'] 47 | trexio_basename = filename_info['trexio_basename'] 48 | state_suffix = filename_info['state_suffix'] 49 | trexio_extension = filename_info['trexio_extension'] 50 | state_id = filename_info['state'] 51 | 52 | try: 53 | res = getFile(filename) 54 | except: 55 | raise 56 | else: 57 | print(filename, 'recognized as', str(res).split('.')[-1].split()[0]) 58 | 59 | res.clean_uncontractions() 60 | 61 | # Metadata 62 | # -------- 63 | 64 | trexio.write_metadata_code_num(trexio_file, 1) 65 | trexio.write_metadata_code(trexio_file, 66 | [str(res).split('.')[-1].split()[0].replace("File","")] ) 67 | if res.author is not None: 68 | trexio.write_metadata_author_num(trexio_file, 1) 69 | trexio.write_metadata_author(trexio_file, [res.author]) 70 | if res.title is not None: 71 | trexio.write_metadata_description(trexio_file, res.title) 72 | 73 | # Electrons 74 | # --------- 75 | 76 | trexio.write_electron_up_num(trexio_file,res.num_alpha) 77 | trexio.write_electron_dn_num(trexio_file,res.num_beta) 78 | 79 | # Nuclei 80 | # ------ 81 | 82 | charge = [] 83 | coord = [] 84 | nucleus_num = len(res.geometry) 85 | 86 | for a in res.geometry: 87 | charge.append(a.charge) 88 | if res.units != 'BOHR': 89 | coord.append([a.coord[0] / a0, a.coord[1] / a0, a.coord[2] / a0]) 90 | else: 91 | coord.append([a.coord[0], a.coord[1], a.coord[2]]) 92 | 93 | trexio.write_nucleus_num(trexio_file, nucleus_num) 94 | trexio.write_nucleus_coord(trexio_file, coord) 95 | # nucleus_charge will be written later after removing core electrons with ECP 96 | 97 | # Transform H1 into H 98 | import re 99 | p = re.compile(r'(\d*)$') 100 | label = [p.sub("", x.name).capitalize() for x in res.geometry] 101 | trexio.write_nucleus_label(trexio_file, label) 102 | 103 | trexio.write_nucleus_point_group(trexio_file, res.point_group) 104 | 105 | 106 | # Basis 107 | 108 | trexio.write_basis_type(trexio_file, "Gaussian") 109 | 110 | # Check whether the basis is Spherical or Cartesian 111 | 112 | cartesian = True 113 | for b in res.basis: 114 | if "d+0" in b.sym: 115 | cartesian = False 116 | break 117 | elif "xx" in b.sym: 118 | break 119 | 120 | # Build basis set 121 | nucleus_index = [] 122 | nucl_shell_num = [] 123 | shell_ang_mom = [] 124 | shell_prim_num = [] 125 | shell_prim_index = [] 126 | shell_factor = [] 127 | exponent = [] 128 | coefficient = [] 129 | prim_factor = [] 130 | curr_shell = -1 131 | curr_shell_idx = 0 132 | ao_shell = [] 133 | prev_idx = None 134 | geom = [ a.coord for a in res.geometry ] 135 | try: 136 | normf = res.normf 137 | except AttributeError: 138 | normf=0 139 | for b in res.basis: 140 | # Warning: assumes +0 is always 1st of spherical functions 141 | if ("y" in b.sym) or ("z" in b.sym): 142 | pass 143 | elif (not cartesian) and (b.sym not in ["s", "x"]) and ("0" not in b.sym): 144 | pass 145 | else: 146 | curr_shell += 1 147 | # count the max_ang_mom of a given shell 148 | if cartesian: 149 | shell_ang_mom.append(b.sym.count("x")) 150 | elif b.sym == "s": 151 | shell_ang_mom.append(0) 152 | elif b.sym == "x": 153 | shell_ang_mom.append(1) 154 | elif "0" in b.sym: 155 | l, _ = get_lm(b.sym) 156 | shell_ang_mom.append(l) 157 | curr_shell_idx = len(exponent) 158 | shell_prim_index.append(curr_shell_idx) 159 | shell_prim_num.append(len(b.prim)) 160 | exponent += [x.expo for x in b.prim] 161 | coefficient += b.coef 162 | prim_factor += [1./x.norm for x in b.prim] 163 | if normf == 0: 164 | shell_factor.append(1./b.norm) 165 | else: 166 | shell_factor.append(1.) 167 | idx = geom.index(b.center) 168 | if idx != prev_idx: 169 | nucleus_index.append(curr_shell) 170 | if len(nucleus_index) > 1: 171 | nucl_shell_num.append(nucleus_index[-1]-nucleus_index[-2]) 172 | 173 | prev_idx = idx 174 | 175 | ao_shell.append(curr_shell) 176 | 177 | shell_num = curr_shell+1 178 | prim_num = len(exponent) 179 | 180 | nucl_shell_num.append(shell_num-nucleus_index[-1]) 181 | 182 | assert(sum(nucl_shell_num) == shell_num) 183 | 184 | # Fix x,y,z in Spherical (don't move this before basis set detection!) 185 | if cartesian: 186 | pass 187 | else: 188 | for b in res.basis: 189 | if b.sym == 'z': 190 | b.sym = 'p+0' 191 | elif b.sym == 'x': 192 | b.sym = 'p+1' 193 | elif b.sym == 'y': 194 | b.sym = 'p-1' 195 | 196 | # ========================================================================== # 197 | # Conversion below is needed to convert arrays according to TREXIO v.2.0 198 | nucleus_index_per_shell = trexio_basis.lists_to_map(nucleus_index, nucl_shell_num) 199 | shell_index_per_prim = trexio_basis.lists_to_map(shell_prim_index, shell_prim_num) 200 | # ========================================================================= # 201 | 202 | # write total number of shell and primitives 203 | trexio.write_basis_shell_num(trexio_file,shell_num) 204 | trexio.write_basis_prim_num(trexio_file,prim_num) 205 | 206 | # write mappings to reconstruct per-atom and per-shell quantities 207 | trexio.write_basis_nucleus_index(trexio_file,nucleus_index_per_shell) 208 | trexio.write_basis_shell_ang_mom(trexio_file,shell_ang_mom) 209 | trexio.write_basis_shell_index(trexio_file,shell_index_per_prim) 210 | 211 | # write normalization factor for each shell 212 | trexio.write_basis_shell_factor(trexio_file,shell_factor) 213 | 214 | # write parameters of the primitives 215 | trexio.write_basis_exponent(trexio_file,exponent) 216 | trexio.write_basis_coefficient(trexio_file,coefficient) 217 | trexio.write_basis_prim_factor(trexio_file,prim_factor) 218 | 219 | # For Gaussian basis sets, basis_r_power is zero 220 | basis_r_power = [0.0 for _ in range(shell_num) ] 221 | trexio.write_basis_r_power(trexio_file,basis_r_power) 222 | 223 | # AO 224 | # -- 225 | 226 | #res.convert_to_cartesian() 227 | trexio.write_ao_cartesian(trexio_file, cartesian) 228 | trexio.write_ao_num(trexio_file, len(res.basis)) 229 | trexio.write_ao_shell(trexio_file, ao_shell) 230 | 231 | ao_ordering = [] 232 | accu = [] 233 | prev_shell = None 234 | 235 | # Re-order AOs (xx,xy,xz,yy,yz,zz) or (d+0,+1,-1,-2,+2,-2,...) 236 | for i,b in enumerate(res.basis): 237 | shell = ao_shell[i] 238 | if shell != prev_shell: 239 | accu.sort() 240 | ao_ordering += accu 241 | accu = [] 242 | accu += [(f_sort(b.sym), i, b.sym )] 243 | prev_shell = shell 244 | accu.sort() 245 | ao_ordering += accu 246 | ao_ordering = [ i for (_,i,_) in ao_ordering ] 247 | 248 | # Normalization 249 | normalization = [] 250 | for i,k in enumerate(ao_ordering): 251 | b = res.basis[k] 252 | orig = res.basis[ao_shell.index(ao_shell[k])] 253 | prim = b.prim 254 | prim_norm = [ j.norm for j in prim ] 255 | oprim = orig.prim 256 | oprim_norm = [ j.norm for j in oprim ] 257 | accum = 0. 258 | for i, ci in enumerate(b.coef): 259 | ci /= prim_norm[i] 260 | for j, cj in enumerate(orig.coef): 261 | cj /= oprim_norm[j] 262 | accum += ci*cj * oprim[i].overlap(oprim[j]) 263 | accum /= orig.norm**2 264 | normalization.append(accum) 265 | trexio.write_ao_normalization(trexio_file, normalization) 266 | 267 | 268 | # MOs 269 | # --- 270 | 271 | if motype is None: 272 | MO_type = res.determinants_mo_type 273 | else: 274 | MO_type = motype 275 | print ("available motypes", res.mo_types) 276 | 277 | allMOs = res.mo_sets[MO_type] 278 | trexio.write_mo_type(trexio_file, MO_type) 279 | 280 | full_mo_set = [(allMOs[i].eigenvalue, i) for i in range(len(allMOs))] 281 | MOindices = [x[1] for x in full_mo_set] 282 | 283 | ## The following commented portion for the future use. 284 | # try: 285 | # closed = [(allMOs[i].eigenvalue, i) for i in res.closed_mos] 286 | # virtual = [(allMOs[i].eigenvalue, i) for i in res.virtual_mos] 287 | # active = [(allMOs[i].eigenvalue, i) for i in res.active_mos] 288 | # except: 289 | # closed = [] 290 | # virtual = [] 291 | # active = [(allMOs[i].eigenvalue, i) for i in range(len(allMOs))] 292 | 293 | # closed = [x[1] for x in closed] 294 | # active = [x[1] for x in active] 295 | # virtual = [x[1] for x in virtual] 296 | # MOindices = closed + active + virtual 297 | 298 | MOs = [] 299 | for i in MOindices: 300 | MOs.append(allMOs[i]) 301 | 302 | mo_num = len(MOindices) 303 | while len(MOindices) < mo_num: 304 | MOindices.append(len(MOindices)) 305 | 306 | MOmap = list(MOindices) 307 | for i in range(len(MOindices)): 308 | MOmap[i] = MOindices.index(i) 309 | 310 | energies = [] 311 | for i in range(mo_num): 312 | energies.append(MOs[i].eigenvalue) 313 | 314 | MoMatrix = [] 315 | sym0 = [i.sym for i in res.mo_sets[MO_type]] 316 | sym = [i.sym for i in res.mo_sets[MO_type]] 317 | for i in range(len(sym)): 318 | if sym0[i] is None: 319 | sym[MOmap[i]] = 'A' 320 | else: 321 | sym[MOmap[i]] = sym0[i] 322 | 323 | MoMatrix = [] 324 | for i in range(len(MOs)): 325 | m = MOs[i] 326 | for j in ao_ordering: 327 | MoMatrix.append(m.vector[j]) 328 | 329 | 330 | trexio.write_mo_num(trexio_file, mo_num) 331 | trexio.write_mo_coefficient(trexio_file, MoMatrix) 332 | trexio.write_mo_symmetry(trexio_file, sym) 333 | 334 | # TODO: occupations are not always provided in the output file ?? 335 | # if res.occ_num is not None: 336 | # OccNum = [] 337 | # for i in MOindices: 338 | # OccNum.append(res.occ_num[MO_type][i]) 339 | # # Not sure about the part below as it might overwrite values from the 340 | # # previous step ! 341 | # while len(OccNum) < mo_num: 342 | # OccNum.append(0.) 343 | # trexio.write_mo_occupation(trexio_file, OccNum) 344 | 345 | lmax = 0 346 | nucl_charge_remove = [] 347 | 348 | nucl_num = len(res.geometry) 349 | lmax_plus_1_per_atom = [] 350 | 351 | map_l = [] 352 | map_nucleus = [] 353 | 354 | if res.pseudo: 355 | ecp_num_total = 0 356 | ecp_coef_total = [] 357 | ecp_exp_total = [] 358 | ecp_power_total = [] 359 | for ecp in res.pseudo: 360 | lmax_atomic = ecp['lmax'] 361 | atom = ecp['atom']-1 362 | 363 | lmax_plus_1_per_atom.append(lmax_atomic) 364 | 365 | nucl_charge_remove.append(ecp['zcore']) 366 | 367 | for l in range(lmax_atomic+1): 368 | l_str = str(l) 369 | 370 | n_per_l = len(ecp[l_str]) 371 | 372 | map_nucleus.extend([atom for _ in range(n_per_l) if n_per_l != 0]) 373 | map_l.extend([l for _ in range(n_per_l) if n_per_l != 0]) 374 | 375 | ecp_num_total += n_per_l 376 | 377 | coef_per_l = [arr[0] for arr in ecp[l_str]] 378 | # shift powers by 2 because of the format 379 | power_per_l = [arr[1]-2 for arr in ecp[l_str]] 380 | exp_per_l = [arr[2] for arr in ecp[l_str]] 381 | 382 | ecp_coef_total.extend(coef_per_l) 383 | ecp_power_total.extend(power_per_l) 384 | ecp_exp_total.extend(exp_per_l) 385 | 386 | 387 | # lmax+1 is one higher that the max angular momentum of the core orbital 388 | # to be removed (per atom) 389 | trexio.write_ecp_max_ang_mom_plus_1(trexio_file, lmax_plus_1_per_atom) 390 | # write core charges to be removed 391 | trexio.write_ecp_z_core(trexio_file, nucl_charge_remove) 392 | # write total num of ECP elements 393 | trexio.write_ecp_num(trexio_file, ecp_num_total) 394 | # write 1-to-1 mapping needed to reconstruct ECPs 395 | trexio.write_ecp_ang_mom(trexio_file, map_l) 396 | trexio.write_ecp_nucleus_index(trexio_file, map_nucleus) 397 | # write ECP quantities in the TREXIO file 398 | trexio.write_ecp_power(trexio_file, ecp_power_total) 399 | trexio.write_ecp_coefficient(trexio_file, ecp_coef_total) 400 | trexio.write_ecp_exponent(trexio_file, ecp_exp_total) 401 | 402 | 403 | for i in range(nucl_num): 404 | charge[i] -= nucl_charge_remove[i] 405 | 406 | # end if res.pseudo: 407 | trexio.write_nucleus_charge(trexio_file, charge) 408 | 409 | # State group 410 | # --------- 411 | if state_id != trexio_file.get_state(): 412 | print("Warning: State ID mismatch between the file and the TREXIO file.") 413 | 414 | state_id = trexio_file.get_state() 415 | trexio.write_state_num(trexio_file,res.num_states) 416 | try: 417 | trexio.write_state_energy(trexio_file,res.energy[0]) 418 | except: 419 | pass 420 | trexio.write_state_current_label(trexio_file, f"State {state_id}") 421 | trexio.write_state_label(trexio_file, [f"State {i}" for i in range(res.num_states)]) 422 | 423 | # Get the basename of the TREXIO file 424 | file_names = [ f"{trexio_basename}_{state_suffix}_{s}{trexio_extension}" for s in range(res.num_states) ] 425 | file_names[0] = f"{trexio_basename}{trexio_extension}" 426 | trexio.write_state_file_name(trexio_file, file_names) 427 | 428 | # CSF group 429 | # --------- 430 | if hasattr(res, 'csf_coefficients') and res.csf_coefficients[state_id]: 431 | try: 432 | num_csfs = len(res.csf_coefficients[state_id]) 433 | except: 434 | num_csfs = len(res.det_coefficients[0]) 435 | 436 | offset_file = 0 437 | trexio.write_csf_coefficient(trexio_file, offset_file, num_csfs, res.csf_coefficients[state_id]) 438 | 439 | # Determinants 440 | # --------- 441 | 442 | # resultsFile has non-empty det_coefficients sometimes 443 | if len(res.det_coefficients[0]) > 1: 444 | 445 | int64_num = int((mo_num-1)/64) + 1 446 | determinant_num = len(res.det_coefficients[0]) 447 | 448 | # sanity check 449 | if res.num_states > 1: 450 | assert determinant_num == len(res.det_coefficients[1]) 451 | 452 | # construct the determinant_list of integer bitfields from resultsFile determinants reprsentation 453 | det_list = [] 454 | for i in range(determinant_num): 455 | det_tmp = [] 456 | orb_list_up = [ orb for orb in res.determinants[i].get("alpha") ] 457 | det_tmp += trexio_det.to_determinant_list(orb_list_up, int64_num) 458 | orb_list_dn = [ orb for orb in res.determinants[i].get("beta") ] 459 | det_tmp += trexio_det.to_determinant_list(orb_list_dn, int64_num) 460 | 461 | det_list.append(det_tmp) 462 | 463 | # write the CI determinants 464 | offset_file = 0 465 | trexio.write_determinant_list(trexio_file, offset_file, determinant_num, det_list) 466 | 467 | # write the CI coefficients 468 | offset_file = 0 469 | trexio.write_determinant_coefficient(trexio_file, offset_file, determinant_num, res.det_coefficients[state_id]) 470 | 471 | # close the file before leaving 472 | trexio_file.close() 473 | 474 | print("Conversion to TREXIO format has been completed for the state ", state_id, " in the file ", trexio_file.filename) 475 | 476 | return 477 | 478 | def run_molden(trexio_file, filename, normalized_basis=True, multiplicity=None, ao_norm=0): 479 | import numpy as np 480 | 481 | with open(filename, 'r') as f: 482 | lines = f.readlines() 483 | 484 | if not lines[0].startswith("[Molden Format]"): 485 | print("File not in Molden format") 486 | raise TypeError 487 | 488 | title = lines[1].strip() 489 | atoms = [] 490 | gto = [] 491 | unit = None 492 | inside = None 493 | cartesian = True 494 | sym = [] 495 | ene = [] 496 | spin = [] 497 | occup = [] 498 | mo_coef = [] 499 | mo = [] 500 | for line in lines: 501 | line = line.strip() 502 | if line == "": 503 | continue 504 | if line.lower().startswith("[atoms]"): 505 | if "au" in line.lower().split()[1]: 506 | unit = "au" 507 | else: 508 | unit = "angs" 509 | inside = "Atoms" 510 | continue 511 | elif line.upper().startswith("[GTO]"): 512 | inside = "GTO" 513 | continue 514 | elif line.upper().startswith("[MO]"): 515 | inside = "MO" 516 | continue 517 | elif line.startswith("[5d]") \ 518 | or line.startswith("[7f]") \ 519 | or line.startswith("[9g]"): 520 | cartesian = False 521 | continue 522 | elif line.startswith("["): 523 | inside = None 524 | if inside == "Atoms": 525 | buffer = line.split() 526 | atoms.append( (buffer[0], int(buffer[2]), float(buffer[3]), 527 | float(buffer[4]), float(buffer[5])) ) 528 | continue 529 | elif inside == "GTO": 530 | gto.append(line) 531 | continue 532 | elif inside == "MO": 533 | in_coef = False 534 | if line.lower().startswith("sym"): 535 | sym.append ( line.split('=')[1].strip() ) 536 | elif line.lower().startswith("ene"): 537 | ene.append ( float(line.split('=')[1].strip()) ) 538 | elif line.lower().startswith("occ"): 539 | occup.append ( float(line.split('=')[1].strip()) ) 540 | elif line.lower().startswith("spin"): 541 | if line.split('=')[1].strip().lower == "alpha": 542 | spin.append(0) 543 | else: 544 | spin.append(1) 545 | else: 546 | in_coef = True 547 | if in_coef: 548 | buffer = line.split() 549 | mo.append( (int(buffer[0])-1, float(buffer[1])) ) 550 | if not in_coef and len(mo) > 0: 551 | mo_coef.append(mo) 552 | mo = [] 553 | continue 554 | 555 | if len(mo) > 0: 556 | mo_coef.append(mo) 557 | 558 | # Metadata 559 | # -------- 560 | 561 | trexio.write_metadata_code_num(trexio_file, 1) 562 | trexio.write_metadata_code(trexio_file, ["Molden"]) 563 | trexio.write_metadata_author_num(trexio_file, 1) 564 | trexio.write_metadata_author(trexio_file, [os.environ["USER"]]) 565 | trexio.write_metadata_description(trexio_file, title) 566 | 567 | # Electrons 568 | # --------- 569 | 570 | elec_num = int(sum(occup)+0.5) 571 | if multiplicity is None: 572 | up_num = 0 573 | dn_num = 0 574 | for o in occup: 575 | if o > 1.0: 576 | up_num += 1 577 | dn_num += 1 578 | elif o == 1.0: 579 | up_num += 1 580 | else: 581 | up_num = (multiplicity-1 + elec_num)/2 582 | dn_num = elec_num - up_num 583 | assert (elec_num == up_num + dn_num) 584 | trexio.write_electron_up_num(trexio_file,up_num) 585 | trexio.write_electron_dn_num(trexio_file,dn_num) 586 | 587 | # Nuclei 588 | # ------ 589 | 590 | charge = [] 591 | coord = [] 592 | nucleus_num = len(atoms) 593 | 594 | coord = [] 595 | label = [] 596 | for a in atoms: 597 | charge.append(float(a[1])) 598 | label.append(a[0]) 599 | if unit != 'au': 600 | coord.append([a[2] / a0, a[3] / a0, a[4] / a0]) 601 | else: 602 | coord.append([a[2], a[3], a[4]]) 603 | 604 | trexio.write_nucleus_num(trexio_file, len(atoms)) 605 | trexio.write_nucleus_coord(trexio_file, coord) 606 | trexio.write_nucleus_charge(trexio_file, charge) 607 | trexio.write_nucleus_label(trexio_file, label) 608 | 609 | 610 | # Basis 611 | # ----- 612 | 613 | nucleus_index = [] 614 | shell_ang_mom = [] 615 | shell_index = [] 616 | shell_prim_index = [] 617 | shell_factor = [] 618 | exponent = [] 619 | coefficient = [] 620 | prim_factor = [] 621 | contraction = None 622 | 623 | shell_id = -1 624 | prim_id = -1 625 | iatom = 0 626 | for line in gto: 627 | buffer = line.replace('D','E').split() 628 | if len(buffer) == 2 and buffer[1] == "0": 629 | iatom = int(buffer[0])-1 630 | elif len(buffer) == 3 and float(buffer[2]) == 1.0: 631 | if contraction is not None: 632 | if normalized_basis: 633 | accum = 0. 634 | n = [ x.norm for x in contraction.prim ] 635 | for i, ci in enumerate(contraction.coef): 636 | ci /= n[i] 637 | for j, cj in enumerate(contraction.coef): 638 | cj /= n[j] 639 | accum += ci*cj * contraction.prim[i].overlap(contraction.prim[j]) 640 | shell_factor.append(1./accum) 641 | else: 642 | shell_factor.append(1.) 643 | shell_id += 1 644 | ang_mom = buffer[0].lower() 645 | nprim = int(buffer[1]) 646 | nucleus_index.append(iatom) 647 | if ang_mom == "s": shell_ang_mom.append(0) 648 | elif ang_mom == "p": shell_ang_mom.append(1) 649 | elif ang_mom == "d": shell_ang_mom.append(2) 650 | elif ang_mom == "f": shell_ang_mom.append(3) 651 | elif ang_mom == "g": shell_ang_mom.append(4) 652 | if ang_mom != "s": ang_mom = "x"*shell_ang_mom[-1] 653 | contraction = resultsFile.contraction() 654 | else: 655 | prim_id += 1 656 | e, c = float(buffer[0]), float(buffer[1]) 657 | shell_prim_index.append(prim_id) 658 | exponent.append(e) 659 | coefficient.append(c) 660 | gauss = resultsFile.gaussian() 661 | gauss.center = coord[iatom] 662 | gauss.expo = e 663 | gauss.sym =ang_mom 664 | contraction.append(c, gauss) 665 | prim_factor.append(1./gauss.norm) 666 | shell_index.append(shell_id) 667 | 668 | if contraction is not None: 669 | if normalized_basis: 670 | accum = 0. 671 | n = [ x.norm for x in contraction.prim ] 672 | for i, ci in enumerate(contraction.coef): 673 | ci /= n[i] 674 | for j, cj in enumerate(contraction.coef): 675 | cj /= n[j] 676 | accum += ci*cj * contraction.prim[i].overlap(contraction.prim[j]) 677 | shell_factor.append(1./accum) 678 | else: 679 | shell_factor.append(1.) 680 | 681 | shell_num = shell_id + 1 682 | prim_num = prim_id + 1 683 | 684 | trexio.write_basis_type(trexio_file, "Gaussian") 685 | 686 | # write total number of shell and primitives 687 | trexio.write_basis_shell_num(trexio_file,shell_num) 688 | trexio.write_basis_prim_num(trexio_file,prim_num) 689 | 690 | # write mappings to reconstruct per-atom and per-shell quantities 691 | trexio.write_basis_nucleus_index(trexio_file,nucleus_index) 692 | trexio.write_basis_shell_ang_mom(trexio_file,shell_ang_mom) 693 | trexio.write_basis_shell_index(trexio_file,shell_index) 694 | 695 | # write normalization factor for each shell 696 | trexio.write_basis_shell_factor(trexio_file,shell_factor) 697 | 698 | # For Gaussian basis sets, basis_r_power is zero 699 | basis_r_power = [0.0 for _ in range(basis_shell_num) ] 700 | trexio.write_basis_r_power(trexio_file,basis_r_power) 701 | 702 | # write parameters of the primitives 703 | trexio.write_basis_exponent(trexio_file,exponent) 704 | trexio.write_basis_coefficient(trexio_file,coefficient) 705 | trexio.write_basis_prim_factor(trexio_file,prim_factor) 706 | 707 | 708 | # AOs 709 | # --- 710 | 711 | if max(shell_ang_mom) < 2: 712 | cartesian=True 713 | 714 | if cartesian: 715 | conv = [ [ 's' ], ['x', 'y', 'z'], ['xx', 'yy', 'zz', 'xy', 'xz', 'yz'], 716 | ['xxx', 'yyy', 'zzz', 'xyy', 'xxy', 'xxz', 'xzz', 'yzz', 'yyz', 'xyz'], 717 | ['xxxx', 'yyyy', 'zzzz', 'xxxy', 'xxxz', 'xyyy', 'yyyz', 'xzzz', 'yzzz', 718 | 'xxyy', 'xxzz', 'yyzz', 'xxyz', 'xyyz', 'xyzz'] ] 719 | else: 720 | conv = [ ['s'], ['p+1', 'p-1', 'p+0'], ['d+0', 'd+1', 'd-1', 'd+2', 'd-2'], 721 | ['f+0', 'f+1', 'f-1', 'f+2', 'f-2', 'f+3', 'f-3'], 722 | ['g+0', 'g+1', 'g-1', 'g+2', 'g-2', 'g+3', 'g-3', 'g+4', 'g-4'] ] 723 | 724 | norm = [] 725 | for l in range(5): 726 | g = resultsFile.gaussian() 727 | gauss.center = (0.,0.,0.) 728 | gauss.expo = 1.0 729 | gauss.sym = conv[l][0] 730 | ref = gauss.norm 731 | norm.append([]) 732 | for m in conv[l]: 733 | g = resultsFile.gaussian() 734 | gauss.center = (0.,0.,0.) 735 | gauss.expo = 1.0 736 | gauss.sym = m 737 | norm[l].append ( gauss.norm / ref ) 738 | 739 | ao = [] 740 | ao_normalization = [] 741 | for l in shell_ang_mom: 742 | if l>4: 743 | raise TypeError("Angular momentum too high: l>4 not supported by Molden format.") 744 | ao.append(conv[l]) 745 | ao_normalization.append(norm[l]) 746 | 747 | ao_shell = [] 748 | ao_ordering = [] 749 | j = 0 750 | for k,l in enumerate(ao): 751 | ao_shell += [ k for _ in l ] 752 | accu = [ (f_sort(x), i+j, norm[shell_ang_mom[k]][i]) for i,x in enumerate(l) ] 753 | accu.sort() 754 | ao_ordering += accu 755 | j += len(l) 756 | ao_normalization = [ i for (_,_,i) in ao_ordering ] 757 | ao_ordering = [ i for (_,i,_) in ao_ordering ] 758 | ao_num = len(ao_ordering) 759 | 760 | trexio.write_ao_num(trexio_file, ao_num) 761 | trexio.write_ao_cartesian(trexio_file, cartesian) 762 | trexio.write_ao_shell(trexio_file, ao_shell) 763 | trexio.write_ao_normalization(trexio_file, ao_normalization) 764 | 765 | # MOs 766 | # --- 767 | 768 | # trexio.write_mo_type(trexio_file, MO_type) 769 | 770 | core = [] 771 | active = [] 772 | virtual = [] 773 | mo_class = [] 774 | for i, o in enumerate(occup): 775 | if o >= 2.: 776 | core.append(i) 777 | mo_class.append("Core") 778 | elif o == 0.: 779 | virtual.append(i) 780 | mo_class.append("Virtual") 781 | else: 782 | active.append(i) 783 | mo_class.append("Active") 784 | 785 | trexio.write_mo_num(trexio_file, len(mo_class)) 786 | MoMatrix = [] 787 | for mo in mo_coef: 788 | vector = np.zeros(ao_num) 789 | for i, x in mo: 790 | vector[i] = x 791 | for i in ao_ordering: 792 | MoMatrix.append(vector[i]) 793 | 794 | trexio.write_mo_spin(trexio_file, spin) 795 | trexio.write_mo_class(trexio_file, mo_class) 796 | trexio.write_mo_occupation(trexio_file, occup) 797 | trexio.write_mo_symmetry(trexio_file, sym) 798 | trexio.write_mo_coefficient(trexio_file, MoMatrix) 799 | 800 | 801 | def run(trexio_filename, filename, filetype, back_end, spin=None, motype=None, state_suffix=None, overwrite=False): 802 | 803 | # Get the basename of the TREXIO file 804 | try: 805 | trexio_basename, trexio_extension = os.path.splitext(os.path.basename(trexio_filename)) 806 | except Exception as e: 807 | trexio_basename = os.path.basename(trexio_filename) 808 | trexio_extension = "" 809 | 810 | 811 | filename_info = {} 812 | filename_info['filename'] = filename 813 | filename_info['trexio_basename'] = trexio_basename 814 | filename_info['state_suffix'] = state_suffix 815 | filename_info['trexio_extension'] = trexio_extension 816 | filename_info['state'] = 0 817 | 818 | if "pyscf" not in filetype.lower() and "gamess" not in filetype.lower(): 819 | trexio_file = trexio.File(trexio_filename, mode='w', back_end=back_end) 820 | 821 | if filetype.lower() == "gaussian": 822 | run_resultsFile(trexio_file, filename_info, motype) 823 | 824 | elif filetype.lower() == "gamess": 825 | # Handle the case where the number of states is greater than 1 826 | try: 827 | res = getFile(filename) 828 | except Exception: 829 | print(f"An error occurred while parsing the file using resultsFile : {Exception}") 830 | 831 | # Open the TREXIO file for writing 832 | trexio_file = trexio.File(trexio_filename, mode='w', back_end=back_end) 833 | run_resultsFile(trexio_file, filename_info, motype) 834 | 835 | # Check the number of states in the quantum chemical calculation file first 836 | if res.num_states > 1: 837 | print(f"Number of states in the quantum chemical calculation file {res.num_states}") 838 | # Create a separate TREXIO file for each state 839 | for s in range(1,res.num_states): 840 | trexio_filename = f"{trexio_basename}_{state_suffix}_{s}{trexio_extension}" 841 | remove_trexio_file(trexio_filename, overwrite) 842 | trexio_file = trexio.File(trexio_filename, mode='w', back_end=back_end) 843 | trexio_file.set_state(s) 844 | filename_info['state'] = s 845 | run_resultsFile(trexio_file, filename_info, motype) 846 | 847 | elif filetype.lower() == "pyscf": 848 | back_end_str = "text" if back_end==trexio.TREXIO_TEXT else "hdf5" 849 | run_pyscf(trexio_filename=trexio_filename, pyscf_checkfile=filename, back_end=back_end_str) 850 | 851 | elif filetype.lower() == "orca": 852 | back_end_str = "text" if back_end==trexio.TREXIO_TEXT else "hdf5" 853 | run_orca(filename=trexio_filename, orca_json=filename, back_end=back_end_str) 854 | 855 | elif filetype.lower() == "crystal": 856 | if spin is None: raise ValueError("You forgot to provide spin for the CRYSTAL->TREXIO converter.") 857 | back_end_str = "text" if back_end==trexio.TREXIO_TEXT else "hdf5" 858 | run_crystal(trexio_filename=trexio_filename, crystal_output=filename, back_end=back_end_str, spin=spin) 859 | 860 | elif filetype.lower() == "molden": 861 | run_molden(trexio_file, filename) 862 | 863 | else: 864 | raise NotImplementedError(f"Conversion from {filetype} to TREXIO is not supported.") 865 | -------------------------------------------------------------------------------- /src/trexio_tools/converters/convert_to.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | convert output of GAMESS/GAU$$IAN to trexio 4 | """ 5 | 6 | import sys 7 | import os 8 | from functools import reduce 9 | from . import cart_sphe as cart_sphe 10 | import numpy as np 11 | 12 | import trexio 13 | 14 | """ 15 | Converter from trexio to fcidump 16 | Symmetry labels are not included 17 | 18 | Written by Johannes Günzl, TU Dresden 2023 19 | """ 20 | def run_fcidump(trexfile, filename, spin_order): 21 | # The Fortran implementation takes i_start and i_end as arguments; here, 22 | # whether an orbital is active is taken from the field in the file 23 | # Active orbitals are carried over as-is, core orbitals are incorporated 24 | # into the integrals; all others are deleted 25 | 26 | if not spin_order in ["block", "interleave"]: 27 | raise ValueError("Supported spin_order options: block (default), interleave") 28 | 29 | with open(filename, "w") as ofile: 30 | if not trexio.has_mo_num(trexfile): 31 | raise Exception("The provided trexio file does not include "\ 32 | "the number of molecular orbitals.") 33 | mo_num = trexio.read_mo_num(trexfile) 34 | if not trexio.has_electron_num(trexfile): 35 | raise Exception("The provided trexio file does not include "\ 36 | "the number of electrons.") 37 | elec_num = trexio.read_electron_num(trexfile) 38 | 39 | occupation = 2 40 | ms2 = 0 41 | if trexio.has_electron_up_num(trexfile) and trexio.has_electron_dn_num(trexfile): 42 | ms2 = trexio.read_electron_up_num(trexfile) \ 43 | - trexio.read_electron_dn_num(trexfile) 44 | if ms2 != 0: 45 | occupation = 1 46 | 47 | spins = None 48 | # Used to check the order of spins in UHF files 49 | if ms2 != 0 and trexio.has_mo_spin(trexfile): 50 | spins = trexio.read_mo_spin(trexfile) 51 | 52 | if trexio.has_mo_class(trexfile): 53 | n_act = 0 54 | n_core = 0 55 | classes = trexio.read_mo_class(trexfile) 56 | # Id of an active orbital among the other active orbs 57 | # -1 means core, -2 means deleted 58 | orb_ids = np.zeros(len(classes), dtype=int) 59 | act_ids = [] 60 | for i, c in enumerate(classes): 61 | if c.lower() == "active": 62 | orb_ids[i] = n_act 63 | act_ids.append(i) 64 | n_act += 1 65 | elif c.lower() == "core": 66 | orb_ids[i] = -1 67 | n_core += 1 68 | else: 69 | orb_ids[i] = -2 70 | else: 71 | # Consider everything active 72 | n_act = mo_num 73 | n_core = 0 74 | orb_ids = np.array([i for i in range(n_act)]) 75 | act_ids = orb_ids 76 | 77 | if n_core != 0 and ms2 != 0: 78 | raise Exception("Core orbitals are not supported for spin polarized systems") 79 | 80 | # Write header 81 | print("&FCI", file=ofile, end = " ") 82 | print(f"NORB={n_act},", file=ofile, end = " ") 83 | print(f"NELEC={elec_num - occupation*n_core},", file=ofile, end = " ") 84 | print(f"MS2={ms2},", file=ofile) 85 | print("ORBSYM=", end="", file=ofile) 86 | for i in range(n_act): 87 | # The symmetry formats between trexio and FCIDUMP differ, so this 88 | # information is not carried over automatically 89 | print("1,", end="", file=ofile) 90 | print("\nISYM=1,", end="", file=ofile) 91 | if ms2 != 0: 92 | print("\nUHF=.TRUE.,", file=ofile) 93 | print("\n&END", file=ofile) 94 | 95 | # Can be used to switch up the indices of printed integrals if necessary 96 | out_index = np.array([i+1 for i in range(n_act)]) 97 | 98 | # If the orbitals are spin-dependent, the order alpha-beta-alpha-beta... 99 | # should be used for ouput (as it is expected e.g. by NECI) 100 | if not spins is None and not np.all(spins == spins[0]): 101 | current_spin_order = "none" 102 | # Check if the current order is alpha-alpha...beta-beta 103 | up = spins[0] 104 | for n, spin in enumerate(spins): 105 | # Check whether first half of orbitals is up, second is down 106 | if not (n < len(spins) // 2 and spin == up \ 107 | or n >= len(spins) // 2 and spin != up): 108 | break 109 | current_spin_order = "block" 110 | 111 | if current_spin_order == "none": 112 | for n, spin in enumerate(spins): 113 | if not (n % 2 == 0 and spin == up \ 114 | or n % 2 == 1 and spin != up): 115 | break 116 | current_spin_order = "interleave" 117 | 118 | if current_spin_order == "none": 119 | print("WARNING: Spin order within the TREXIO file was not recognized.", \ 120 | "The order will be kept as-is.") 121 | 122 | if not current_spin_order == spin_order: 123 | print("WARNING: The order of spin orbitals will be changed as requested.", \ 124 | "This might break compatibility with other data in the TREXIO file, " \ 125 | "e.g. CI determinant information") 126 | if current_spin_order == "block" and spin_order == "interleave": 127 | # The (1-n_act) term sets back the beta orbitals by the number of alpha orbitals 128 | out_index = np.array([2*i + (1 - n_act)*(i // (n_act // 2)) + 1 for i in range(n_act)]) 129 | elif current_spin_order == "interleave" and spin_order == "block": 130 | out_index = np.array((i%2)*(n_act // 2) + i // 2 + 1 for i in range(n_act)) 131 | 132 | fcidump_threshold = 1e-10 133 | int3 = np.zeros((n_act, n_act, 2), dtype=float) 134 | int2 = np.zeros((n_act, n_act, 2), dtype=float) 135 | 136 | # Two electron integrals 137 | offset = 0 138 | buffer_size = 1000 139 | integrals_eof = False 140 | if trexio.has_mo_2e_int_eri(trexfile): 141 | while not integrals_eof: 142 | indices, vals, read_integrals, integrals_eof \ 143 | = trexio.read_mo_2e_int_eri(trexfile, offset, buffer_size) 144 | offset += read_integrals 145 | 146 | for integral in range(read_integrals): 147 | val = vals[integral] 148 | 149 | if np.abs(val) < fcidump_threshold: 150 | continue 151 | ind = indices[integral] 152 | ii = ind[0] 153 | jj = ind[1] 154 | kk = ind[2] 155 | ll = ind[3] 156 | act_ind = [orb_ids[x] for x in ind] 157 | i = act_ind[0] 158 | j = act_ind[1] 159 | k = act_ind[2] 160 | l = act_ind[3] 161 | 162 | if i >= 0 and j >= 0 and k >= 0 and l >= 0: 163 | # Convert from dirac to chemists' notation 164 | print(val, out_index[i], out_index[k], out_index[j], out_index[l], file=ofile) 165 | 166 | # Since the integrals are added, the multiplicity needs to be screened 167 | if not (ii >= kk and ii >= jj and ii >= ll and jj >= ll and (ii != jj or ll >= kk)): 168 | continue 169 | 170 | if i >= 0 and k >= 0 and j == -1 and jj == ll: 171 | int3[i, k, 0] += val 172 | if i != k: 173 | int3[k, i, 0] += val 174 | 175 | if i >= 0 and l >= 0 and j == -1 and jj == kk: 176 | int3[i, l, 1] += val 177 | if i != l: 178 | int3[l, i, 1] += val 179 | elif i >= 0 and j >= 0 and l == -1 and ll == kk: 180 | int3[i, j, 1] += val 181 | if i != j: 182 | int3[j, i, 1] += val 183 | 184 | if j >= 0 and l >= 0 and i == -1 and ii == kk: 185 | int3[j, l, 0] += val 186 | if j != l: 187 | int3[l, j, 0] += val 188 | 189 | if j >= 0 and k >= 0 and i == -1 and ii == ll: 190 | int3[j, k, 1] += val 191 | if j != k: 192 | int3[k, j, 1] += val 193 | elif l >= 0 and k >= 0 and i == -1 and ii == jj: 194 | int3[l, k, 1] += val 195 | if l != k: 196 | int3[k, l, 1] += val 197 | 198 | if i == -1 and ii == kk and j == -1 and jj == ll: 199 | int2[ii, jj, 0] = val 200 | int2[jj, ii, 0] = val 201 | 202 | if i == -1 and ii == ll and j == -1 and jj == kk: 203 | int2[ii, jj, 1] = val 204 | int2[jj, ii, 1] = val 205 | if i == -1 and ii == jj and k == -1 and kk == ll: 206 | int2[ii, kk, 1] = val 207 | int2[kk, ii, 1] = val 208 | 209 | # Hamiltonian 210 | if trexio.has_mo_1e_int_core_hamiltonian(trexfile): 211 | core_ham = trexio.read_mo_1e_int_core_hamiltonian(trexfile) 212 | # Add core Fock operator 213 | for j in range(n_act): 214 | jj = act_ids[j] 215 | for i in range(n_act): 216 | ii = act_ids[i] 217 | int3[i, j, 0] = core_ham[ii, jj] + occupation*int3[i, j, 0] - int3[i, j, 1] 218 | 219 | for a in range(n_act): 220 | for b in range(a, n_act): 221 | val = int3[a, b, 0] 222 | if np.abs(val) > fcidump_threshold: 223 | print(val, out_index[b], out_index[a], 0, 0, file=ofile) 224 | 225 | # Core energy 226 | if trexio.has_nucleus_repulsion(trexfile): 227 | core = trexio.read_nucleus_repulsion(trexfile) 228 | for i in range(mo_num): 229 | if orb_ids[i] == -1: 230 | core += occupation*core_ham[i, i] 231 | for j in range(mo_num): 232 | if orb_ids[j] == -1: 233 | core += occupation*int2[i, j, 0] - int2[i, j, 1] 234 | 235 | print(core, 0, 0, 0, 0, file=ofile) 236 | 237 | def run_molden(t, filename): 238 | 239 | out = ["[Molden Format]"] 240 | out += ["Converted from TREXIO"] 241 | 242 | out += ["[Atoms] AU"] 243 | 244 | nucl_num = trexio.read_nucleus_num(t) 245 | charge = trexio.read_nucleus_charge(t) 246 | if trexio.has_ecp_z_core(t): 247 | z_core = trexio.read_ecp_z_core(t) 248 | charge = [ x + y for x,y in zip(charge,z_core) ] 249 | name = trexio.read_nucleus_label(t) 250 | coord = trexio.read_nucleus_coord(t) 251 | for i in range(nucl_num): 252 | out += [ "%3s %4d %4d %18.14f %18.14f %18.14f"%tuple( 253 | [name[i], i+1, int(charge[i])] + list(coord[i]) ) ] 254 | 255 | 256 | 257 | basis_type = trexio.read_basis_type(t) 258 | if basis_type.lower() == "gaussian": 259 | 260 | out += ["[GTO]"] 261 | prim_num = trexio.read_basis_prim_num(t) 262 | shell_num = trexio.read_basis_shell_num(t) 263 | nucleus_index = trexio.read_basis_nucleus_index(t) 264 | shell_ang_mom = trexio.read_basis_shell_ang_mom(t) 265 | shell_factor = trexio.read_basis_shell_factor(t) 266 | shell_index = trexio.read_basis_shell_index(t) 267 | exponent = trexio.read_basis_exponent(t) 268 | coefficient = trexio.read_basis_coefficient(t) 269 | prim_factor = trexio.read_basis_prim_factor(t) 270 | 271 | # For Gaussian basis sets, basis_r_power is zero by default 272 | if trexio.has_basis_r_power(t): 273 | basis_r_power = trexio.read_basis_r_power(t) 274 | else: 275 | basis_r_power = [0.0 for _ in range(basis_shell_num) ] 276 | 277 | contr = [ { "exponent" : [], 278 | "coefficient" : [], 279 | "prim_factor" : [] } for _ in range(shell_num) ] 280 | for j in range(prim_num): 281 | i = shell_index[j] 282 | contr[i]["exponent"] += [ exponent[j] ] 283 | contr[i]["coefficient"] += [ coefficient[j] ] 284 | contr[i]["prim_factor"] += [ prim_factor[j] ] 285 | 286 | basis = {} 287 | for k in range(nucl_num): 288 | basis[k] = { "shell_ang_mom" : [], 289 | "shell_factor" : [], 290 | "shell_index" : [], 291 | "contr" : [] } 292 | 293 | for i in range(shell_num): 294 | k = nucleus_index[i] 295 | basis[k]["shell_ang_mom"] += [ shell_ang_mom[i] ] 296 | basis[k]["shell_factor"] += [ shell_factor[i] ] 297 | basis[k]["shell_index"] += [ shell_index[i] ] 298 | basis[k]["contr"] += [ contr[i] ] 299 | 300 | 301 | ang_mom_conv = [ "s", "p", "d", "f", "g" ] 302 | for k in range(nucl_num): 303 | out += [ "%6d 0"%(k+1) ] 304 | for l in range(len(basis[k]["shell_index"])): 305 | ncontr = len(basis[k]["contr"][l]["exponent"]) 306 | out += [ "%2s %8d 1.00" % ( 307 | ang_mom_conv[ basis[k]["shell_ang_mom"][l] ], 308 | ncontr) ] 309 | for j in range(ncontr): 310 | out += [ "%20.10E %20.10E"%( 311 | basis[k]["contr"][l]["exponent"][j], 312 | basis[k]["contr"][l]["coefficient"][j] ) ] 313 | out += [""] 314 | 315 | # end if basis_type.lower() == "gaussian" 316 | 317 | 318 | 319 | # 5D: D 0, D+1, D-1, D+2, D-2 320 | # 6D: xx, yy, zz, xy, xz, yz 321 | # 322 | # 7F: F 0, F+1, F-1, F+2, F-2, F+3, F-3 323 | # 10F: xxx, yyy, zzz, xyy, xxy, xxz, xzz, yzz, yyz, xyz 324 | # 325 | # 9G: G 0, G+1, G-1, G+2, G-2, G+3, G-3, G+4, G-4 326 | # 15G: xxxx yyyy zzzz xxxy xxxz yyyx yyyz zzzx zzzy, 327 | # xxyy xxzz yyzz xxyz yyxz zzxy 328 | 329 | mo_num = trexio.read_mo_num(t) 330 | cartesian = trexio.read_ao_cartesian(t) 331 | if cartesian: 332 | order = [ [0], 333 | [0, 1, 2], 334 | [0, 3, 5, 2, 3, 4], 335 | [0, 6, 9, 3, 1, 2, 5, 8, 7, 4], 336 | [0, 10, 14, 1, 2, 6, 11, 9, 13, 3, 5, 12, 4, 7, 8] ] 337 | else: 338 | out += [ "[5D]", "[7F]", "[9G]" ] 339 | order = [ [0], [1, 2, 0], 340 | [ i for i in range(5) ], 341 | [ i for i in range(7) ], 342 | [ i for i in range(9) ] ] 343 | 344 | ao_num = trexio.read_ao_num(t) 345 | o = [] 346 | icount = 0 347 | for i in range(shell_num): 348 | l = shell_ang_mom[i] 349 | for k in order[l]: 350 | o.append( icount+k ) 351 | icount += len(order[l]) 352 | 353 | 354 | elec_alpha_num = trexio.read_electron_up_num(t) 355 | elec_beta_num = trexio.read_electron_dn_num(t) 356 | if trexio.has_mo_occupation(t): 357 | occ = trexio.read_mo_occupation(t) 358 | else: 359 | occ = [ 0. for i in range(mo_num) ] 360 | for i in range(elec_alpha_num): 361 | occ[i] += 1. 362 | for i in range(elec_beta_num): 363 | occ[i] += 1. 364 | 365 | mo_coef = trexio.read_mo_coefficient(t) 366 | if trexio.has_mo_symmetry(t): 367 | sym = trexio.read_mo_symmetry(t) 368 | else: 369 | sym = [ "A1" for _ in range(mo_num) ] 370 | 371 | 372 | out += ["[MO]"] 373 | 374 | for i in range(mo_num): 375 | out += [ "Sym= %s"%(sym[i]), 376 | # "Ene= 0.0", 377 | "Spin= Alpha", 378 | "Occup= %f"%(occ[i]) ] 379 | for k in range(ao_num): 380 | out += [ "%6d %20.10E"%(k+1, mo_coef[i,o[k]]) ] 381 | 382 | if trexio.has_ecp_z_core(t): 383 | out += [ "[CORE]" ] 384 | for i,k in enumerate(z_core): 385 | out += [ "%4d : %4d"%(i, k) ] 386 | 387 | out += [ "" ] 388 | out_file = open(filename,"w") 389 | out_file.write("\n".join(out)) 390 | 391 | return 392 | 393 | 394 | 395 | 396 | def run_cart_phe(inp, filename, to_cartesian): 397 | out = trexio.File(filename, 'u', inp.back_end) 398 | 399 | shell_ang_mom = trexio.read_basis_shell_ang_mom(inp) 400 | 401 | # Build transformation matrix 402 | count_sphe = 0 403 | count_cart = 0 404 | accu = [] 405 | shell = [] 406 | # This code iterates over all shells, and should do it in the order they are in ao_shells 407 | ao_shell = trexio.read_ao_shell(inp) 408 | i = 0 409 | while i < len(ao_shell): 410 | she = ao_shell[i] 411 | l = shell_ang_mom[she] 412 | p, r = count_cart, count_sphe 413 | (x,y) = cart_sphe.data[l].shape 414 | count_cart += x 415 | count_sphe += y 416 | q, s = count_cart, count_sphe 417 | accu.append( (l, p,q, r,s) ) 418 | if to_cartesian == 1: 419 | n = x 420 | i += y 421 | elif to_cartesian == 0: 422 | n = y 423 | i += x 424 | for _ in range(n): 425 | shell.append(she) 426 | 427 | cart_normalization = np.ones(count_cart) 428 | R = np.zeros( (count_cart, count_sphe) ) 429 | for (l, p,q, r,s) in accu: 430 | R[p:q,r:s] = cart_sphe.data[l] 431 | cart_normalization[p:q] = cart_sphe.normalization[l] 432 | 433 | ao_num_in = trexio.read_ao_num(inp) 434 | 435 | normalization = np.array( [ 1. ] * ao_num_in ) 436 | if trexio.has_ao_normalization(inp): 437 | normalization = trexio.read_ao_normalization(inp) 438 | 439 | for i,f in enumerate(normalization): 440 | cart_normalization[i] *= f 441 | 442 | if to_cartesian == 1: # sphe -> cart 443 | S = np.zeros((count_cart, count_cart)) 444 | S = R.T @ R 445 | S_inv = np.linalg.inv(S) 446 | 447 | ao_num_out = count_cart 448 | R0 = R @ S_inv 449 | R1 = R 450 | R = R1 451 | 452 | elif to_cartesian == 0: # cart -> sphe 453 | S = np.zeros((count_cart, count_cart)) 454 | S = R @ R.T 455 | S_inv = np.linalg.pinv(S) 456 | 457 | ao_num_out = count_sphe 458 | R0 = R.T 459 | R1 = R.T @ S_inv 460 | R = R1 461 | cart_normalization = np.array([1. for _ in range(count_sphe)]) 462 | 463 | 464 | elif to_cartesian == -1: 465 | R = np.eye(ao_num_in) 466 | 467 | # Update AOs 468 | trexio.write_ao_cartesian(out, to_cartesian) 469 | trexio.write_ao_num(out, ao_num_out) 470 | trexio.write_ao_shell(out, shell) 471 | 472 | trexio.write_ao_normalization(out, cart_normalization) 473 | 474 | basis_type = trexio.read_basis_type(inp) 475 | if basis_type.lower() == "numerical": 476 | """ 477 | Although d_z^2 is the reference for both sphe and cart, 478 | the actual definition of said orbital is different -> shell_factor must be adapted 479 | """ 480 | if trexio.has_basis_shell_factor(inp) and trexio.has_basis_shell_ang_mom(inp): 481 | shell_fac = trexio.read_basis_shell_factor(inp) 482 | l = trexio.read_basis_shell_ang_mom(inp) 483 | 484 | for i in range(len(shell_fac)): 485 | if l[i] == 2 or l[i] == 3: 486 | shell_fac[i] *= 2 487 | elif l[i] == 4 or l[i] == 5: 488 | shell_fac[i] *= 8 489 | elif l[i] == 4 or l[i] == 5: 490 | shell_fac[i] *= 8 491 | elif l[i] == 6 or l[i] == 7: 492 | shell_fac[i] *= 16 493 | trexio.write_basis_shell_factor(out, shell_fac) 494 | 495 | """ 496 | If spherical harmonics are used for the angular part, radial and angular 497 | coordinates are completely seperated. The cartesian polynomials, however, 498 | mix radial and angular coordinates. Thus, r_power needs to be adapted to cancel 499 | out the radial dependence of the polynomials. 500 | """ 501 | 502 | r_power = [0.0 for _ in shell_ang_mom ] 503 | 504 | r_power_sign = -1 505 | if to_cartesian == 0: 506 | r_power_sign = +1 507 | for i, ang_mom in enumerate(shell_ang_mom): 508 | r_power[i] = ang_mom * r_power_sign 509 | 510 | trexio.write_basis_r_power(out, r_power) 511 | 512 | # Update MOs 513 | if trexio.has_mo_coefficient(inp): 514 | X = trexio.read_mo_coefficient(inp) 515 | Y = X @ R0.T 516 | trexio.write_mo_coefficient(out, Y) 517 | 518 | # Update 1e Integrals 519 | if trexio.has_ao_1e_int_overlap(inp): 520 | X = trexio.read_ao_1e_int_overlap(inp) 521 | Y = R @ X @ R.T 522 | trexio.write_ao_1e_int_overlap(out, Y) 523 | 524 | 525 | if trexio.has_ao_1e_int_kinetic(inp): 526 | X = trexio.read_ao_1e_int_kinetic(inp) 527 | trexio.write_ao_1e_int_kinetic(out, R @ X @ R.T) 528 | 529 | if trexio.has_ao_1e_int_potential_n_e(inp): 530 | X = trexio.read_ao_1e_int_potential_n_e(inp) 531 | trexio.write_ao_1e_int_potential_n_e(out, R @ X @ R.T) 532 | 533 | if trexio.has_ao_1e_int_ecp(inp): 534 | X = trexio.read_ao_1e_int_ecp(inp) 535 | trexio.write_ao_1e_int_ecp(out, R @ X @ R.T) 536 | 537 | if trexio.has_ao_1e_int_core_hamiltonian(inp): 538 | X = trexio.read_ao_1e_int_core_hamiltonian(inp) 539 | trexio.write_ao_1e_int_core_hamiltonian(out, R @ X @ R.T) 540 | 541 | if trexio.has_ao_2e_int(inp) and False: 542 | m = ao_num_in 543 | n = ao_num_out 544 | size_max = trexio.read_ao_2e_int_eri_size(inp) 545 | 546 | offset = 0 547 | icount = size_max+1 548 | feof = False 549 | print("Reading integrals...") 550 | W = np.zeros( (m,m,m,m) ) 551 | while not feof: 552 | buffer_index, buffer_values, icount, feof = trexio.read_ao_2e_int_eri(inp, offset, icount) 553 | print (icount, feof) 554 | offset += icount 555 | for p in range(icount): 556 | i, j, k, l = buffer_index[p] 557 | print (i,j,k,l) 558 | W[i,j,k,l] = buffer_values[p] 559 | W[k,j,i,l] = buffer_values[p] 560 | W[i,l,k,j] = buffer_values[p] 561 | W[k,l,i,j] = buffer_values[p] 562 | W[j,i,l,k] = buffer_values[p] 563 | W[j,k,l,i] = buffer_values[p] 564 | W[l,i,j,k] = buffer_values[p] 565 | W[l,k,j,i] = buffer_values[p] 566 | print("Transformation #1") 567 | T = W.reshape( (m, m*m*m) ) 568 | U = T.T @ R.T 569 | print("Transformation #2") 570 | W = U.reshape( (m, m*m*n) ) 571 | T = W.T @ R.T 572 | print("Transformation #3") 573 | U = T.reshape( (m, m*n*n) ) 574 | W = U.T @ R.T 575 | print("Transformation #4") 576 | T = W.reshape( (m, n*n*n) ) 577 | U = T.T @ R.T 578 | W = U.reshape( (n,n,n,n) ) 579 | 580 | buffer_index = [] 581 | buffer_values = [] 582 | print (m, " -> ", n ) 583 | for l in range(n): 584 | for k in range(n): 585 | for j in range(l,n): 586 | for i in range(k,n): 587 | if i==j and k 0: 616 | return 617 | 618 | run_cart_phe(t, filename, to_cartesian=1) 619 | return 620 | 621 | def run_spherical(t, filename): 622 | # Start by copying the file 623 | os.system('cp -r %s %s' % (t.filename, filename)) 624 | cartesian = trexio.read_ao_cartesian(t) 625 | if cartesian == 0: 626 | return 627 | 628 | run_cart_phe(t, filename, to_cartesian=0) 629 | return 630 | 631 | 632 | def run(trexio_filename, filename, filetype, spin_order): 633 | 634 | print (filetype) 635 | trexio_file = trexio.File(trexio_filename,mode='r',back_end=trexio.TREXIO_AUTO) 636 | 637 | if filetype.lower() == "molden": 638 | run_molden(trexio_file, filename) 639 | elif filetype.lower() == "cartesian": 640 | run_cartesian(trexio_file, filename) 641 | elif filetype.lower() == "spherical": 642 | run_spherical(trexio_file, filename) 643 | # elif filetype.lower() == "normalized_aos": 644 | # run_normalized_aos(trexio_file, filename) 645 | elif filetype.lower() == "fcidump": 646 | run_fcidump(trexio_file, filename, spin_order) 647 | else: 648 | raise NotImplementedError(f"Conversion from TREXIO to {filetype} is not supported.") 649 | 650 | -------------------------------------------------------------------------------- /src/trexio_tools/converters/orca_to_trexio.py: -------------------------------------------------------------------------------- 1 | def orca_to_trexio( 2 | orca_json: str = "orca.json", 3 | filename: str = "trexio.hdf5", 4 | back_end: str = "hdf5" 5 | ): 6 | # load python packages 7 | import os 8 | import json 9 | import numpy as np 10 | import scipy.special 11 | 12 | # ## ORCA -> TREX-IO 13 | # - how to install trexio 14 | # - pip install trexio 15 | 16 | # import trexio 17 | import trexio 18 | 19 | # Logger 20 | from logging import getLogger 21 | logger = getLogger("orca-trexio").getChild(__name__) 22 | 23 | logger.info(f"orca_json = {orca_json}") 24 | logger.info(f"trexio_filename = {filename}") 25 | logger.info("Conversion starts...") 26 | 27 | 28 | with open(orca_json, 'r') as f: 29 | data = json.load(f) 30 | 31 | # trexio back end handling 32 | if back_end.lower() == "hdf5": 33 | trexio_back_end = trexio.TREXIO_HDF5 34 | elif back_end.lower() == "text": 35 | trexio_back_end = trexio.TREXIO_TEXT 36 | else: 37 | raise NotImplementedError(f"{back_end} back-end is not supported.") 38 | 39 | trexio_file = trexio.File(filename, mode='w', back_end=trexio_back_end) 40 | 41 | natoms = len(data["Molecule"]["Atoms"]) 42 | #print(f"Natoms={natoms}") 43 | coord = [] 44 | chemical_symbol_list = [] 45 | atom_charges_list = [] 46 | ecp_charge_list = [] 47 | ecp_charge = 0 48 | elec_num = 0 49 | total_charge = data["Molecule"]["Charge"] 50 | multiplicity = data["Molecule"]["Multiplicity"] 51 | orbital_labels = data["Molecule"]["MolecularOrbitals"]["OrbitalLabels"] 52 | has_ecp = [] 53 | for i in range(natoms): 54 | atom = data["Molecule"]["Atoms"][i] 55 | coord.append(atom["Coords"]) 56 | chemical_symbol_list.append(atom["ElementLabel"]) 57 | elec_num += atom["NuclearCharge"] 58 | try: 59 | atom["ECPs"] 60 | has_ecp.append(True) 61 | N_core = atom["ECPs"]["N_core"] 62 | ecp_charge_list.append(N_core) 63 | ecp_charge += N_core 64 | except: 65 | has_ecp.append(False) 66 | atom_charges_list.append(atom["NuclearCharge"]) 67 | elec_num = elec_num - total_charge - ecp_charge 68 | 69 | # Check coordinate type 70 | coord_type = data["Molecule"]["CoordinateUnits"] 71 | coord = np.array(coord) 72 | if coord_type == "Angs": 73 | # Convert to Bohrs 74 | for i in range(natoms): 75 | coord[i] = 1.8897259886 * coord[i] 76 | 77 | # Assuming multiplicity = (elec_up - elec_dn) + 1 78 | electron_up_num = int((elec_num + multiplicity - 1)//2) 79 | electron_dn_num = int(elec_num - electron_up_num) 80 | 81 | ########################################## 82 | # Structure info 83 | ########################################## 84 | trexio.write_electron_up_num(trexio_file, electron_up_num) 85 | trexio.write_electron_dn_num(trexio_file, electron_dn_num) 86 | trexio.write_nucleus_num(trexio_file, len(coord)) 87 | trexio.write_nucleus_coord(trexio_file, coord) 88 | trexio.write_nucleus_charge(trexio_file, atom_charges_list) 89 | trexio.write_nucleus_label(trexio_file, chemical_symbol_list) 90 | ########################################## 91 | # basis set info 92 | ########################################## 93 | # check the orders of the spherical atomic basis in orca!! 94 | # L, ml 95 | # pz, px, py = (0,+1,-1) 96 | # dz2, dxz, dyz, dx2y2, dxy = (0,+1,-1,+2,-2) 97 | # gto.spheric_labels(mol, fmt="%d, %s, %s, %s") 98 | # ORCA ordering -- TREXIO ordering 99 | # ----------------------------------------------------- 100 | # for s -> s -- trexio: (0) 101 | # for p -> pz, px, py -- trexio: (-1,0,1) 102 | # for d -> dz2, dxz, dyz, dx2y2, dxy -- trexio: (-2, -1, 0, 1, 2) 103 | # for l -> m=(0 -1 +1 -2 +2 ... -l +l) -- (-l, ..., 0, ..., +l) 104 | nucleus_num = natoms 105 | atom_nshells = [] 106 | atom_shell_ids = [] 107 | bas_angular = [] 108 | bas_nprim = [] 109 | bas_ctr_coeff = [] 110 | bas_exp = [] 111 | basis_shell_num = 0 112 | for i in range(nucleus_num): 113 | atom = data["Molecule"]["Atoms"][i] 114 | nshells = len(atom["Basis"]) 115 | atom_nshells.append(nshells) 116 | shell_ids = [] 117 | for k in range(nshells): 118 | shell_ids.append(i) 119 | bas_angular.append(atom["Basis"][k]["Shell"]) 120 | bas_nprim.append(len(atom["Basis"][k]["Exponents"])) 121 | bas_exp.append(atom["Basis"][k]["Exponents"]) 122 | bas_ctr_coeff.append(atom["Basis"][k]["Coefficients"]) 123 | atom_shell_ids.append(shell_ids) 124 | 125 | try: 126 | S_matrix = np.array(data["Molecule"]["S-Matrix"]) 127 | T_matrix = np.array(data["Molecule"]["T-Matrix"]) 128 | H_matrix = np.array(data["Molecule"]["H-Matrix"]) 129 | readS = True 130 | except: 131 | readS = False 132 | dict_ang_mom = dict() 133 | dict_ang_mom['s'] = 0 134 | dict_ang_mom['p'] = 1 135 | dict_ang_mom['d'] = 2 136 | dict_ang_mom['f'] = 3 137 | dict_ang_mom['g'] = 4 138 | dict_ang_mom['h'] = 5 139 | dict_ang_mom['i'] = 6 140 | 141 | basis_type = "Gaussian" 142 | basis_shell_num = int(np.sum([atom_nshells[i] for i in range(nucleus_num)])) 143 | nucleus_index = [] 144 | for i in range(nucleus_num): 145 | for _ in range(len(atom_shell_ids[i])): 146 | nucleus_index.append(i) 147 | shell_ang_mom = [dict_ang_mom[bas_angular[i]] for i in range(basis_shell_num)] 148 | basis_prim_num = int(np.sum([bas_nprim[i] for i in range(basis_shell_num)])) 149 | 150 | basis_exponent = [] 151 | basis_coefficient = [] 152 | for i in range(basis_shell_num): 153 | for bas_exp_i in bas_exp[i]: 154 | basis_exponent.append(float(bas_exp_i)) 155 | for bas_ctr_coeff_i in bas_ctr_coeff[i]: 156 | basis_coefficient.append(float(bas_ctr_coeff_i)) 157 | 158 | basis_shell_index = [] 159 | for i in range(basis_shell_num): 160 | for _ in range(len(bas_exp[i])): 161 | basis_shell_index.append(i) 162 | 163 | # normalization factors 164 | basis_shell_factor = [1.0 for _ in range(basis_shell_num)] # 1.0 in ORCA 165 | 166 | # power of r is always zero for Gaussian functions 167 | basis_r_power = [0.0 for _ in range(basis_shell_num) ] 168 | 169 | def my_factorial2(n): 170 | if n < 0: 171 | return(1) 172 | else: 173 | return(scipy.special.factorial2(n)) 174 | 175 | 176 | def gto_norm(alpha, ax, ay, az): 177 | val = ((alpha + alpha)/np.pi)**(3/4)*((4*alpha)**((ax + ay + az)/2))/((my_factorial2(2*ax - 1) * \ 178 | my_factorial2(2*ay - 1) * \ 179 | my_factorial2(2*az - 1))**(1/2)) 180 | return(val) 181 | 182 | # gto_norm(l, expnt) => l is angmom, expnt is exponent 183 | # Note!! Here, the normalization factor of the spherical part 184 | # are not included. The normalization factor is computed according 185 | # to Eq.8 of the following paper 186 | # H.B.S and M.J.F, Int. J. Quant. Chem., 54(1995), 83-87. 187 | basis_prim_factor = [] 188 | for prim_i in range(basis_prim_num): 189 | coeff = basis_coefficient[prim_i] 190 | expnt = basis_exponent[prim_i] 191 | l_num = shell_ang_mom[basis_shell_index[prim_i]] 192 | basis_prim_factor.append( 193 | gto_norm(expnt, l_num, 0, 0) 194 | ) 195 | 196 | ########################################## 197 | # basis set info 198 | ########################################## 199 | trexio.write_basis_type(trexio_file, basis_type) # 200 | trexio.write_basis_shell_num(trexio_file, basis_shell_num) # 201 | trexio.write_basis_prim_num(trexio_file, basis_prim_num) # 202 | trexio.write_basis_nucleus_index(trexio_file, nucleus_index) # 203 | trexio.write_basis_shell_ang_mom(trexio_file, shell_ang_mom) # 204 | trexio.write_basis_shell_factor(trexio_file, basis_shell_factor) # 205 | trexio.write_basis_r_power(trexio_file, basis_r_power) # 206 | trexio.write_basis_shell_index(trexio_file, basis_shell_index) # 207 | trexio.write_basis_exponent(trexio_file, basis_exponent) # 208 | trexio.write_basis_coefficient(trexio_file, basis_coefficient) # 209 | trexio.write_basis_prim_factor(trexio_file, basis_prim_factor) # 210 | ########################################## 211 | # ao info 212 | ########################################## 213 | # to be fixed!! for Victor case mol.cart is false, but the basis seems cartesian... 214 | cart = False 215 | if cart: 216 | ao_cartesian = 1 217 | else: 218 | ao_cartesian = 0 # spherical basis representation 219 | ao_shell = [] 220 | for i, ang_mom in enumerate(shell_ang_mom): 221 | for _ in range(2 * ang_mom + 1): 222 | ao_shell.append(i) 223 | ao_num = len(ao_shell) 224 | 225 | # 1.0 in pyscf (because spherical) 226 | ao_normalization = [1.0 for _ in range(ao_num)] 227 | 228 | ########################################## 229 | # ao info 230 | ########################################## 231 | trexio.write_ao_cartesian(trexio_file, ao_cartesian) # 232 | trexio.write_ao_num(trexio_file, ao_num) # 233 | trexio.write_ao_shell(trexio_file, ao_shell) # 234 | trexio.write_ao_normalization(trexio_file, ao_normalization) # 235 | if readS: 236 | trexio.write_ao_1e_int_overlap(trexio_file, S_matrix) 237 | trexio.write_ao_1e_int_kinetic(trexio_file, T_matrix) 238 | trexio.write_ao_1e_int_potential_n_e(trexio_file, H_matrix) 239 | 240 | ########################################## 241 | # mo info 242 | ########################################## 243 | mo_type = "MO" 244 | 245 | mo_occupation_read = [] 246 | mo_energy_read = [] 247 | mo_coeff_read = [] 248 | for k in data['Molecule']['MolecularOrbitals']['MOs']: 249 | mo_occupation_read.append(k['Occupancy']) 250 | mo_coeff_read.append(k['MOCoefficients']) 251 | mo_energy_read.append(k['OrbitalEnergy']) 252 | 253 | # check if the pySCF calculation is Restricted or Unrestricted 254 | # Restricted -> RHF,RKS,ROHF,OROKS 255 | # Unrestricted -> UHF,UKS 256 | 257 | if len(mo_energy_read) == 2: 258 | if isinstance(mo_energy_read[0], float): 259 | spin_restricted = True 260 | else: 261 | spin_restricted = False 262 | else: 263 | spin_restricted = True 264 | 265 | # the followins are given to TREXIO file lager if spin_restricted == False, 266 | mo_coefficient_all = [] 267 | mo_occupation_all = [] 268 | mo_energy_all = [] 269 | mo_spin_all = [] 270 | 271 | # mo read part starts both for alpha and beta spins 272 | for ns, spin in enumerate([0, 1]): 273 | 274 | if spin_restricted: 275 | mo_occupation = mo_occupation_read 276 | mo_energy = mo_energy_read 277 | mo_coeff = mo_coeff_read 278 | if spin == 1: # 0 is alpha(up), 1 is beta(dn) 279 | logger.info("This is spin-restricted calculation.") 280 | logger.info("Skip the MO conversion step for beta MOs.") 281 | break 282 | else: 283 | logger.info( 284 | f"MO conversion step for {spin}-spin MOs. 0 is alpha(up), 1 is beta(dn)." 285 | ) 286 | mo_occupation = mo_occupation_read[ns] 287 | mo_energy = mo_energy_read[ns] 288 | mo_coeff = mo_coeff_read[ns] 289 | 290 | mo_num = len(mo_coeff[0]) 291 | 292 | mo_spin_all += [spin for _ in range(mo_num)] 293 | 294 | 295 | logger.debug(mo_num) 296 | logger.debug(len(mo_coeff)) 297 | logger.debug(mo_occupation) 298 | logger.debug(mo_energy) 299 | # logger.info(mo_coeff) 300 | 301 | # check if MOs are descending order with respect to "mo occ" 302 | # this is usually true, but not always true for 303 | # RO (restricted open-shell) calculations. 304 | order_bool = all( 305 | [ 306 | True if mo_occupation[i] >= mo_occupation[i + 1] else False 307 | for i in range(len(mo_occupation) - 1) 308 | ] 309 | ) 310 | logger.info(f"MO occupations are in the descending order ? -> {order_bool}") 311 | if not order_bool: 312 | logger.warning("MO occupations are not in the descending order!!") 313 | logger.warning("RO (restricted open-shell) calculations?") 314 | logger.warning("Reordering MOs...") 315 | # reordering MOs. 316 | # descending order (mo occ) 317 | reo_moocc_index = np.argsort(mo_occupation)[::-1] 318 | mo_occupation_o = [mo_occupation[l_num] for l_num in reo_moocc_index] 319 | mo_energy_o = [mo_energy[l_num] for l_num in reo_moocc_index] 320 | mo_coeff_o = [mo_coeff[l_num] for l_num in reo_moocc_index] 321 | # descending order (mo energy) 322 | mo_coeff = [] 323 | mo_occupation = [] 324 | mo_energy = [] 325 | set_mo_occupation = sorted(list(set(mo_occupation_o)), reverse=True) 326 | for mo_occ in set_mo_occupation: 327 | mo_re_index = [ 328 | i for i, mo in enumerate(mo_occupation_o) if mo == mo_occ 329 | ] 330 | mo_occupation_t = [mo_occupation_o[l_num] for l_num in mo_re_index] 331 | mo_energy_t = [mo_energy_o[l_num] for l_num in mo_re_index] 332 | mo_coeff_t = [mo_coeff_o[l_num] for l_num in mo_re_index] 333 | reo_ene_index = np.argsort(mo_energy_t) 334 | mo_occupation += [mo_occupation_t[l_num] for l_num in reo_ene_index] 335 | mo_energy += [mo_energy_t[l_num] for l_num in reo_ene_index] 336 | mo_coeff += [mo_coeff_t[l_num] for l_num in reo_ene_index] 337 | 338 | logger.debug("--mo_num--") 339 | logger.debug(mo_num) 340 | logger.debug("--len(mo_coeff)--") 341 | logger.debug(len(mo_coeff)) 342 | logger.debug("--mo_occupation--") 343 | logger.debug(mo_occupation) 344 | logger.debug("--mo_energy--") 345 | logger.debug(mo_energy) 346 | # logger.debug(mo_coeff) 347 | 348 | # saved mo_occ and mo_energy 349 | mo_occupation_all += list(mo_occupation) 350 | mo_energy_all += list(mo_energy) 351 | 352 | # permutation_matrix = [] # for ao and mo swaps, used later 353 | 354 | # molecular coefficient reordering 355 | # TREX-IO employs (m=-l,..., 0, ..., +l) for spherical basis 356 | mo_coefficient = [] 357 | 358 | for mo_i in range(mo_num): 359 | mo = mo_coeff[mo_i] 360 | mo_coeff_buffer = [] 361 | 362 | perm_list = [] 363 | perm_n = 0 364 | for ao_i, ao_c in enumerate(mo): 365 | 366 | # initialization 367 | if ao_i == 0: 368 | mo_coeff_for_reord = [] 369 | current_ang_mom = -1 370 | 371 | # read ang_mom (i.e., angular momentum of the shell) 372 | bas_i = ao_shell[ao_i] 373 | ang_mom = shell_ang_mom[bas_i] 374 | 375 | previous_ang_mom = current_ang_mom 376 | current_ang_mom = ang_mom 377 | 378 | # set multiplicity 379 | multiplicity = 2 * ang_mom + 1 380 | # print(f"multiplicity = {multiplicity}") 381 | 382 | # check if the buffer is null, when ang_mom changes 383 | if previous_ang_mom != current_ang_mom: 384 | assert len(mo_coeff_for_reord) == 0 385 | 386 | if current_ang_mom == 0: # s shell 387 | # print("s shell/no permutation is needed.") 388 | # print("(pyscf notation): s(l=0)") 389 | # print("(trexio notation): s(l=0)") 390 | reorder_index = [0] 391 | 392 | elif current_ang_mom == 1: # p shell 393 | 394 | # print("p shell/permutation is needed.") 395 | # print("(pyscf notation): px(l=+1), py(l=-1), pz(l=0)") 396 | # print("(trexio notation): pz(l=0), px(l=+1), py(l=-1)") 397 | reorder_index = [2, 0, 1] 398 | 399 | elif current_ang_mom >= 2: # > d shell 400 | 401 | # print("> d shell/permutation is needed.") 402 | # print( 403 | # "(pyscf) e.g., f3,-3(l=-3), f3,-2(l=-2), f3,-1(l=-1), \ 404 | # f3,0(l=0), f3,+1(l=+1), f3,+2(l=+2), f3,+3(l=+3)" 405 | # ) 406 | # print( 407 | # "(trexio) e.g, f3,0(l=0), f3,+1(l=+1), f3,-1(l=-1), \ 408 | # f3,+2(l=+2), f3,-2(l=-2), f3,+3(l=+3), f3,-3(l=-3)" 409 | # ) 410 | l0_index = int((multiplicity - 1) / 2) 411 | reorder_index = [l0_index] 412 | for i in range(1, int((multiplicity - 1) / 2) + 1): 413 | reorder_index.append(l0_index + i) 414 | reorder_index.append(l0_index - i) 415 | 416 | else: 417 | raise ValueError("A wrong value was set to current_ang_mom.") 418 | 419 | mo_coeff_for_reord.append(ao_c) 420 | 421 | # write MOs!! 422 | if len(mo_coeff_for_reord) == multiplicity: 423 | # print("--write MOs!!--") 424 | mo_coeff_buffer += [ 425 | mo_coeff_for_reord[i] for i in reorder_index 426 | ] 427 | 428 | # reset buffer 429 | mo_coeff_for_reord = [] 430 | 431 | # print("--write perm_list") 432 | perm_list += list(np.array(reorder_index) + perm_n) 433 | perm_n = perm_n + len(reorder_index) 434 | 435 | mo_coefficient.append(mo) 436 | # permutation_matrix.append(perm_list) 437 | 438 | mo_coefficient_all += mo_coefficient 439 | 440 | # MOs read part end both for alpha and beta spins[l] 441 | logger.debug("len(mo_coefficient_all)") 442 | logger.debug(len(mo_coefficient_all)) 443 | logger.debug("len(mo_occupation_all)") 444 | logger.debug(len(mo_occupation_all)) 445 | logger.debug("len(mo_spin_all)") 446 | logger.debug(len(mo_spin_all)) 447 | 448 | # Conversion from Python complex -> real, complex separately. 449 | # force WF complex 450 | force_wf_complex = False 451 | if force_wf_complex: 452 | complex_flag = True 453 | # check if the MOs have imag.! 454 | else: 455 | imag_flags = [] 456 | for mo in mo_coefficient_all: 457 | imag_flags += list(np.isreal(list(np.real_if_close(mo, tol=100)))) 458 | # print(imag_flags) 459 | if all(imag_flags): 460 | complex_flag = False 461 | else: 462 | complex_flag = True 463 | 464 | if complex_flag: 465 | logger.info("The WF is complex") 466 | mo_coefficient_real = [] 467 | mo_coefficient_imag = [] 468 | 469 | for mo__ in mo_coefficient_all: 470 | mo_real_b = [] 471 | mo_imag_b = [] 472 | for coeff in mo__: 473 | mo_real_b.append(coeff.real) 474 | mo_imag_b.append(coeff.imag) 475 | mo_coefficient_real.append(mo_real_b) 476 | mo_coefficient_imag.append(mo_imag_b) 477 | 478 | else: 479 | logger.info("The WF is real") 480 | mo_coefficient_real = [list(np.array(mo).real) for mo in mo_coefficient_all] 481 | 482 | logger.debug("--MOs Done--") 483 | ########################################## 484 | # mo info 485 | ########################################## 486 | trexio.write_mo_type(trexio_file, mo_type) # 487 | 488 | if complex_flag: 489 | trexio.write_mo_num(trexio_file, len(mo_coefficient_real)) # 490 | trexio.write_mo_coefficient(trexio_file, mo_coefficient_real) # 491 | trexio.write_mo_coefficient_im(trexio_file, mo_coefficient_imag) # 492 | else: 493 | trexio.write_mo_num(trexio_file, len(mo_coefficient_real)) # 494 | trexio.write_mo_coefficient(trexio_file, mo_coefficient_real) # 495 | 496 | trexio.write_mo_occupation(trexio_file, mo_occupation_all) # 497 | 498 | trexio.write_mo_spin(trexio_file, mo_spin_all) # 499 | ########################################## 500 | # ECP 501 | ########################################## 502 | # internal format of ORCA 503 | # See Manual 5.0.4 pg : 497 504 | """ 505 | ------------- 506 | atom: 507 | nelec (number of core electrons) 508 | lmax (max. angular momentum for Ul to indicate |l> TREXIO hdf5 file 2 | # author: Kosuke Nakano 3 | # maintainer: Kosuke Nakano 4 | # email: "kousuke_1123@icloud.com" 5 | 6 | # Logger 7 | from logging import getLogger 8 | logger = getLogger("pyscf-trexio").getChild(__name__) 9 | 10 | 11 | def pyscf_to_trexio( 12 | pyscf_checkfile: str = "pyscf.chk", 13 | trexio_filename: str = "trexio.hdf5", 14 | back_end: str = "hdf5" 15 | ): 16 | """PySCF to TREXIO converter.""" 17 | 18 | # load python packages 19 | import os 20 | import numpy as np 21 | # load pyscf packages 22 | from pyscf import scf 23 | from pyscf.pbc import scf as pbcscf 24 | 25 | # ## pySCF -> TREX-IO 26 | # - how to install trexio 27 | # - pip install trexio 28 | 29 | # import trexio 30 | import trexio 31 | 32 | logger.info(f"pyscf_checkfile = {pyscf_checkfile}") 33 | logger.info(f"trexio_filename = {trexio_filename}") 34 | logger.info("Conversion starts...") 35 | 36 | # pyscf instances 37 | mol = scf.chkfile.load_mol(pyscf_checkfile) 38 | mf = scf.chkfile.load(pyscf_checkfile, "scf") 39 | 40 | # PBC info 41 | try: 42 | mol.a 43 | pbc_flag = True 44 | except AttributeError: 45 | pbc_flag = False 46 | logger.info(f"PBC flag = {pbc_flag}") 47 | 48 | # twist_average info 49 | if pbc_flag: 50 | try: 51 | k = mf["kpt"] 52 | twist_average = False 53 | logger.info("Single-k calculation") 54 | k_list = [k] 55 | if all([k_i == 0.0 for k_i in list(k)]): 56 | logger.info("k = gamma point") 57 | logger.info("The generated WF will be real.") 58 | force_wf_complex = False 59 | else: 60 | logger.info("k = general point") 61 | logger.info("The generated WF will be complex.") 62 | force_wf_complex = True 63 | except KeyError: 64 | twist_average = True 65 | logger.info("Twisted-average calculation") 66 | logger.info("Separate TREXIO files are generated") 67 | logger.info( 68 | "The correspondence between the index \ 69 | and k is written in kp_info.dat" 70 | ) 71 | logger.info("The generated WFs will be complex.") 72 | force_wf_complex = True 73 | with open("kp_info.dat", "w") as f: 74 | f.write("# k_index, kx, ky, kz\n") 75 | k_list = mf["kpts"] 76 | finally: 77 | mol = pbcscf.chkfile.load_cell(pyscf_checkfile) 78 | k_list = mol.get_scaled_kpts(k_list) 79 | logger.info(k_list) 80 | 81 | else: 82 | twist_average = False 83 | k_list = [[0.0, 0.0, 0.0]] 84 | force_wf_complex = False 85 | 86 | # if pbc_flag == true, check if ecp or pseudo 87 | if pbc_flag: 88 | if len(mol._pseudo) > 0: 89 | logger.error( 90 | "TREXIO does not support 'pseudo' format for PBC. Use 'ecp'." 91 | ) 92 | raise NotImplementedError 93 | 94 | if twist_average: 95 | logger.warning( 96 | f"WF at each k point is saved in a separate file kXXXX_{trexio_filename}" 97 | ) 98 | logger.warning("k points information is stored in kp_info.dat file.") 99 | 100 | # each k WF is stored as a separate file!! 101 | # for an open-boundary calculation, and a single-k one, 102 | # k_index is a dummy variable 103 | for k_index, k_vec in enumerate(k_list): 104 | assert len(k_vec) == 3 # 3d variable 105 | # set a filename 106 | if twist_average: 107 | logger.info(f"kpt={k_vec}") 108 | filename = os.path.join( 109 | os.path.dirname(trexio_filename), 110 | f"k{k_index}_" + os.path.basename(trexio_filename), 111 | ) 112 | logger.info(f"filename={filename}") 113 | with open("kp_info.dat", "a") as f: 114 | f.write(f"{k_index} {k_vec[0]} {k_vec[1]} {k_vec[2]}\n") 115 | else: 116 | filename = trexio_filename 117 | 118 | if os.path.exists(filename): 119 | logger.warning(f"TREXIO file {filename} already exists and will be removed before conversion.") 120 | if back_end.lower() == "hdf5": 121 | os.remove(filename) 122 | else: 123 | raise NotImplementedError(f"Please remove the {filename} directory manually.") 124 | 125 | # trexio back end handling 126 | if back_end.lower() == "hdf5": 127 | trexio_back_end = trexio.TREXIO_HDF5 128 | elif back_end.lower() == "text": 129 | trexio_back_end = trexio.TREXIO_TEXT 130 | else: 131 | raise NotImplementedError(f"{back_end} back-end is not supported.") 132 | 133 | # trexio file 134 | trexio_file = trexio.File(filename, mode="w", back_end=trexio_back_end) 135 | 136 | ########################################## 137 | # PBC info 138 | ########################################## 139 | if pbc_flag: 140 | Bohr = 0.5291772109 141 | if isinstance(mol.a, list): 142 | a = np.array(mol.a[0]) / Bohr # angstrom -> bohr 143 | b = np.array(mol.a[1]) / Bohr # angstrom -> bohr 144 | c = np.array(mol.a[2]) / Bohr # angstrom -> bohr 145 | else: 146 | hmatrix=np.fromstring(mol.a, dtype=np.float64, sep=' ').reshape((3,3),order='C') 147 | a=np.array(hmatrix[0,:])/ Bohr # angstrom -> bohr 148 | b=np.array(hmatrix[1,:])/ Bohr # angstrom -> bohr 149 | c=np.array(hmatrix[2,:])/ Bohr # angstrom -> bohr 150 | 151 | k_point = k_vec 152 | periodic = True 153 | else: 154 | periodic = False 155 | 156 | # pbc and cell info 157 | trexio.write_pbc_periodic(trexio_file, periodic) 158 | if pbc_flag: 159 | trexio.write_cell_a(trexio_file, a) 160 | trexio.write_cell_b(trexio_file, b) 161 | trexio.write_cell_c(trexio_file, c) 162 | trexio.write_pbc_k_point(trexio_file, k_point) 163 | 164 | # structure info. 165 | electron_up_num, electron_dn_num = mol.nelec 166 | nucleus_num = mol.natm 167 | atom_charges_list = [mol.atom_charge(i) for i in range(mol.natm)] 168 | """ 169 | atom_nelec_core_list = [ 170 | mol.atom_nelec_core(i) for i in range(mol.natm) 171 | ] 172 | atomic_number_list = [ 173 | mol.atom_charge(i) + mol.atom_nelec_core(i) 174 | for i in range(mol.natm) 175 | ] 176 | """ 177 | chemical_symbol_list = [mol.atom_pure_symbol(i) for i in range(mol.natm)] 178 | atom_symbol_list = [mol.atom_symbol(i) for i in range(mol.natm)] 179 | coords_np = mol.atom_coords(unit="Bohr") 180 | 181 | ########################################## 182 | # Structure info 183 | ########################################## 184 | trexio.write_electron_up_num(trexio_file, electron_up_num) 185 | trexio.write_electron_dn_num(trexio_file, electron_dn_num) 186 | trexio.write_nucleus_num(trexio_file, nucleus_num) 187 | trexio.write_nucleus_charge(trexio_file, atom_charges_list) 188 | trexio.write_nucleus_label(trexio_file, chemical_symbol_list) 189 | trexio.write_nucleus_coord(trexio_file, coords_np) 190 | 191 | ########################################## 192 | # basis set info 193 | ########################################## 194 | # check the orders of the spherical atomic basis in pyscf!! 195 | # gto.spheric_labels(mol, fmt="%d, %s, %s, %s") 196 | # for s -> s 197 | # for p -> px, py, pz 198 | # for l >= d -> m=(-l ... 0 ... +l) 199 | 200 | basis_type = "Gaussian" # thanks anthony! 201 | basis_shell_num = int(np.sum([mol.atom_nshells(i) for i in range(nucleus_num)])) 202 | nucleus_index = [] 203 | for i in range(nucleus_num): 204 | for _ in range(len(mol.atom_shell_ids(i))): 205 | nucleus_index.append(i) 206 | shell_ang_mom = [mol.bas_angular(i) for i in range(basis_shell_num)] 207 | basis_prim_num = int(np.sum([mol.bas_nprim(i) for i in range(basis_shell_num)])) 208 | 209 | basis_exponent = [] 210 | basis_coefficient = [] 211 | for i in range(basis_shell_num): 212 | for bas_exp in mol.bas_exp(i): 213 | basis_exponent.append(float(bas_exp)) 214 | for bas_ctr_coeff in mol.bas_ctr_coeff(i): 215 | basis_coefficient.append(float(bas_ctr_coeff)) 216 | 217 | basis_shell_index = [] 218 | for i in range(basis_shell_num): 219 | for _ in range(len(mol.bas_exp(i))): 220 | basis_shell_index.append(i) 221 | 222 | # normalization factors 223 | basis_shell_factor = [1.0 for _ in range(basis_shell_num)] # 1.0 in pySCF 224 | 225 | # power of r is always zero for Gaussian functions 226 | basis_r_power = [0.0 for _ in range(basis_shell_num) ] 227 | 228 | # gto_norm(l, expnt) => l is angmom, expnt is exponent 229 | # Note!! Here, the normalization factor of the spherical part 230 | # are not included. The normalization factor is computed according 231 | # to Eq.8 of the following paper 232 | # H.B.S and M.J.F, Int. J. Quant. Chem., 54(1995), 83-87. 233 | basis_prim_factor = [] 234 | for prim_i in range(basis_prim_num): 235 | coeff = basis_coefficient[prim_i] 236 | expnt = basis_exponent[prim_i] 237 | l_num = shell_ang_mom[basis_shell_index[prim_i]] 238 | basis_prim_factor.append( 239 | mol.gto_norm(l_num, expnt) / np.sqrt(4 * np.pi) * np.sqrt(2 * l_num + 1) 240 | ) 241 | 242 | ########################################## 243 | # ao info 244 | ########################################## 245 | # to be fixed!! for Victor case mol.cart is false, but the basis seems cartesian... 246 | if mol.cart: 247 | ao_cartesian = 99999 248 | else: 249 | ao_cartesian = 0 # spherical basis representation 250 | ao_shell = [] 251 | for i, ang_mom in enumerate(shell_ang_mom): 252 | for _ in range(2 * ang_mom + 1): 253 | ao_shell.append(i) 254 | ao_num = len(ao_shell) 255 | 256 | # 1.0 in pyscf (because spherical) 257 | ao_normalization = [1.0 for _ in range(ao_num)] 258 | 259 | ########################################## 260 | # mo info 261 | ########################################## 262 | mo_type = "MO" 263 | 264 | if twist_average: 265 | mo_occupation_read = mf["mo_occ"][k_index] 266 | mo_energy_read = mf["mo_energy"][k_index] 267 | mo_coeff_read = mf["mo_coeff"][k_index] 268 | else: 269 | mo_occupation_read = mf["mo_occ"] 270 | mo_energy_read = mf["mo_energy"] 271 | mo_coeff_read = mf["mo_coeff"] 272 | 273 | # check if the pySCF calculation is Restricted or Unrestricted 274 | # Restricted -> RHF,RKS,ROHF,OROKS 275 | # Unrestricted -> UHF,UKS 276 | 277 | if len(mo_energy_read) == 2: 278 | if isinstance(mo_energy_read[0], float): 279 | spin_restricted = True 280 | else: 281 | spin_restricted = False 282 | else: 283 | spin_restricted = True 284 | 285 | # the followins are given to TREXIO file lager if spin_restricted == False, 286 | mo_coefficient_all = [] 287 | mo_occupation_all = [] 288 | mo_energy_all = [] 289 | mo_spin_all = [] 290 | 291 | # mo read part starts both for alpha and beta spins 292 | for ns, spin in enumerate([0, 1]): 293 | 294 | if spin_restricted: 295 | mo_occupation = mo_occupation_read 296 | mo_energy = mo_energy_read 297 | mo_coeff = mo_coeff_read 298 | if spin == 1: # 0 is alpha(up), 1 is beta(dn) 299 | logger.info("This is spin-restricted calculation.") 300 | logger.info("Skip the MO conversion step for beta MOs.") 301 | break 302 | else: 303 | logger.info( 304 | f"MO conversion step for {spin}-spin MOs. 0 is alpha(up), 1 is beta(dn)." 305 | ) 306 | mo_occupation = mo_occupation_read[ns] 307 | mo_energy = mo_energy_read[ns] 308 | mo_coeff = mo_coeff_read[ns] 309 | 310 | mo_num = len(mo_coeff[0]) 311 | 312 | mo_spin_all += [spin for _ in range(mo_num)] 313 | 314 | # mo reordering because mo_coeff[:,mo_i]!! 315 | mo_coeff = [mo_coeff[:, mo_i] for mo_i in range(mo_num)] 316 | 317 | logger.debug(mo_num) 318 | logger.debug(len(mo_coeff)) 319 | logger.debug(mo_occupation) 320 | logger.debug(mo_energy) 321 | # logger.info(mo_coeff) 322 | 323 | # check if MOs are descending order with respect to "mo occ" 324 | # this is usually true, but not always true for 325 | # RO (restricted open-shell) calculations. 326 | order_bool = all( 327 | [ 328 | True if mo_occupation[i] >= mo_occupation[i + 1] else False 329 | for i in range(len(mo_occupation) - 1) 330 | ] 331 | ) 332 | logger.info(f"MO occupations are in the descending order ? -> {order_bool}") 333 | if not order_bool: 334 | logger.warning("MO occupations are not in the descending order!!") 335 | logger.warning("RO (restricted open-shell) calculations?") 336 | logger.warning("Reordering MOs...") 337 | # reordering MOs. 338 | # descending order (mo occ) 339 | reo_moocc_index = np.argsort(mo_occupation)[::-1] 340 | mo_occupation_o = [mo_occupation[l_num] for l_num in reo_moocc_index] 341 | mo_energy_o = [mo_energy[l_num] for l_num in reo_moocc_index] 342 | mo_coeff_o = [mo_coeff[l_num] for l_num in reo_moocc_index] 343 | # descending order (mo energy) 344 | mo_coeff = [] 345 | mo_occupation = [] 346 | mo_energy = [] 347 | set_mo_occupation = sorted(list(set(mo_occupation_o)), reverse=True) 348 | for mo_occ in set_mo_occupation: 349 | mo_re_index = [ 350 | i for i, mo in enumerate(mo_occupation_o) if mo == mo_occ 351 | ] 352 | mo_occupation_t = [mo_occupation_o[l_num] for l_num in mo_re_index] 353 | mo_energy_t = [mo_energy_o[l_num] for l_num in mo_re_index] 354 | mo_coeff_t = [mo_coeff_o[l_num] for l_num in mo_re_index] 355 | reo_ene_index = np.argsort(mo_energy_t) 356 | mo_occupation += [mo_occupation_t[l_num] for l_num in reo_ene_index] 357 | mo_energy += [mo_energy_t[l_num] for l_num in reo_ene_index] 358 | mo_coeff += [mo_coeff_t[l_num] for l_num in reo_ene_index] 359 | 360 | logger.debug("--mo_num--") 361 | logger.debug(mo_num) 362 | logger.debug("--len(mo_coeff)--") 363 | logger.debug(len(mo_coeff)) 364 | logger.debug("--mo_occupation--") 365 | logger.debug(mo_occupation) 366 | logger.debug("--mo_energy--") 367 | logger.debug(mo_energy) 368 | # logger.debug(mo_coeff) 369 | 370 | # saved mo_occ and mo_energy 371 | mo_occupation_all += list(mo_occupation) 372 | mo_energy_all += list(mo_energy) 373 | 374 | # permutation_matrix = [] # for ao and mo swaps, used later 375 | 376 | # molecular coefficient reordering 377 | # TREX-IO employs (m=-l,..., 0, ..., +l) for spherical basis 378 | mo_coefficient = [] 379 | 380 | for mo_i in range(mo_num): 381 | mo = mo_coeff[mo_i] 382 | mo_coeff_buffer = [] 383 | 384 | perm_list = [] 385 | perm_n = 0 386 | for ao_i, ao_c in enumerate(mo): 387 | 388 | # initialization 389 | if ao_i == 0: 390 | mo_coeff_for_reord = [] 391 | current_ang_mom = -1 392 | 393 | # read ang_mom (i.e., angular momentum of the shell) 394 | bas_i = ao_shell[ao_i] 395 | ang_mom = shell_ang_mom[bas_i] 396 | 397 | previous_ang_mom = current_ang_mom 398 | current_ang_mom = ang_mom 399 | 400 | # set multiplicity 401 | multiplicity = 2 * ang_mom + 1 402 | # print(f"multiplicity = {multiplicity}") 403 | 404 | # check if the buffer is null, when ang_mom changes 405 | if previous_ang_mom != current_ang_mom: 406 | assert len(mo_coeff_for_reord) == 0 407 | 408 | if current_ang_mom == 0: # s shell 409 | # print("s shell/no permutation is needed.") 410 | # print("(pyscf notation): s(l=0)") 411 | # print("(trexio notation): s(l=0)") 412 | reorder_index = [0] 413 | 414 | elif current_ang_mom == 1: # p shell 415 | 416 | # print("p shell/permutation is needed.") 417 | # print("(pyscf notation): px(l=+1), py(l=-1), pz(l=0)") 418 | # print("(trexio notation): pz(l=0), px(l=+1), py(l=-1)") 419 | reorder_index = [2, 0, 1] 420 | 421 | elif current_ang_mom >= 2: # > d shell 422 | 423 | # print("> d shell/permutation is needed.") 424 | # print( 425 | # "(pyscf) e.g., f3,-3(l=-3), f3,-2(l=-2), f3,-1(l=-1), \ 426 | # f3,0(l=0), f3,+1(l=+1), f3,+2(l=+2), f3,+3(l=+3)" 427 | # ) 428 | # print( 429 | # "(trexio) e.g, f3,0(l=0), f3,+1(l=+1), f3,-1(l=-1), \ 430 | # f3,+2(l=+2), f3,-2(l=-2), f3,+3(l=+3), f3,-3(l=-3)" 431 | # ) 432 | l0_index = int((multiplicity - 1) / 2) 433 | reorder_index = [l0_index] 434 | for i in range(1, int((multiplicity - 1) / 2) + 1): 435 | reorder_index.append(l0_index + i) 436 | reorder_index.append(l0_index - i) 437 | 438 | else: 439 | raise ValueError("A wrong value was set to current_ang_mom.") 440 | 441 | mo_coeff_for_reord.append(ao_c) 442 | 443 | # write MOs!! 444 | if len(mo_coeff_for_reord) == multiplicity: 445 | # print("--write MOs!!--") 446 | mo_coeff_buffer += [ 447 | mo_coeff_for_reord[i] for i in reorder_index 448 | ] 449 | 450 | # reset buffer 451 | mo_coeff_for_reord = [] 452 | 453 | # print("--write perm_list") 454 | perm_list += list(np.array(reorder_index) + perm_n) 455 | perm_n = perm_n + len(reorder_index) 456 | 457 | mo_coefficient.append(mo_coeff_buffer) 458 | # permutation_matrix.append(perm_list) 459 | 460 | mo_coefficient_all += mo_coefficient 461 | 462 | # MOs read part end both for alpha and beta spins[l] 463 | logger.debug("len(mo_coefficient_all)") 464 | logger.debug(len(mo_coefficient_all)) 465 | logger.debug("len(mo_occupation_all)") 466 | logger.debug(len(mo_occupation_all)) 467 | logger.debug("len(mo_spin_all)") 468 | logger.debug(len(mo_spin_all)) 469 | 470 | # Conversion from Python complex -> real, complex separately. 471 | # force WF complex 472 | if force_wf_complex: 473 | complex_flag = True 474 | # check if the MOs have imag.! 475 | else: 476 | imag_flags = [] 477 | for mo in mo_coefficient_all: 478 | imag_flags += list(np.isreal(list(np.real_if_close(mo, tol=100)))) 479 | # print(imag_flags) 480 | if all(imag_flags): 481 | complex_flag = False 482 | else: 483 | complex_flag = True 484 | 485 | if complex_flag: 486 | logger.info("The WF is complex") 487 | mo_coefficient_real = [] 488 | mo_coefficient_imag = [] 489 | 490 | for mo__ in mo_coefficient_all: 491 | mo_real_b = [] 492 | mo_imag_b = [] 493 | for coeff in mo__: 494 | mo_real_b.append(coeff.real) 495 | mo_imag_b.append(coeff.imag) 496 | mo_coefficient_real.append(mo_real_b) 497 | mo_coefficient_imag.append(mo_imag_b) 498 | 499 | else: 500 | logger.info("The WF is real") 501 | mo_coefficient_real = [list(np.array(mo).real) for mo in mo_coefficient_all] 502 | 503 | logger.debug("--MOs Done--") 504 | 505 | ########################################## 506 | # basis set info 507 | ########################################## 508 | trexio.write_basis_type(trexio_file, basis_type) # 509 | trexio.write_basis_shell_num(trexio_file, basis_shell_num) # 510 | trexio.write_basis_prim_num(trexio_file, basis_prim_num) # 511 | trexio.write_basis_nucleus_index(trexio_file, nucleus_index) # 512 | trexio.write_basis_shell_ang_mom(trexio_file, shell_ang_mom) # 513 | trexio.write_basis_r_power(trexio_file, basis_r_power) # 514 | trexio.write_basis_shell_factor(trexio_file, basis_shell_factor) # 515 | trexio.write_basis_shell_index(trexio_file, basis_shell_index) # 516 | trexio.write_basis_exponent(trexio_file, basis_exponent) # 517 | trexio.write_basis_coefficient(trexio_file, basis_coefficient) # 518 | trexio.write_basis_prim_factor(trexio_file, basis_prim_factor) # 519 | 520 | ########################################## 521 | # ao info 522 | ########################################## 523 | trexio.write_ao_cartesian(trexio_file, ao_cartesian) # 524 | trexio.write_ao_num(trexio_file, ao_num) # 525 | trexio.write_ao_shell(trexio_file, ao_shell) # 526 | trexio.write_ao_normalization(trexio_file, ao_normalization) # 527 | 528 | ########################################## 529 | # mo info 530 | ########################################## 531 | trexio.write_mo_type(trexio_file, mo_type) # 532 | 533 | if complex_flag: 534 | trexio.write_mo_num(trexio_file, len(mo_coefficient_real)) # 535 | trexio.write_mo_coefficient(trexio_file, mo_coefficient_real) # 536 | trexio.write_mo_coefficient_im(trexio_file, mo_coefficient_imag) # 537 | else: 538 | trexio.write_mo_num(trexio_file, len(mo_coefficient_real)) # 539 | trexio.write_mo_coefficient(trexio_file, mo_coefficient_real) # 540 | 541 | trexio.write_mo_occupation(trexio_file, mo_occupation_all) # 542 | 543 | trexio.write_mo_spin(trexio_file, mo_spin_all) # 544 | 545 | ########################################## 546 | # ao integrals 547 | ########################################## 548 | # trexio.write_ao_1e_int_overlap(trexio_file, intor_int1e_ovlp) 549 | # trexio.write_ao_1e_int_kinetic(trexio_file, intor_int1e_kin) 550 | # trexio.write_ao_1e_int_potential_n_e(trexio_file, intor_int1e_nuc) 551 | 552 | ########################################## 553 | # ECP 554 | ########################################## 555 | # internal format of pyscf 556 | # https://pyscf.org/pyscf_api_docs/pyscf.gto.html?highlight=ecp#module-pyscf.gto.ecp 557 | """ 558 | { atom: (nelec, # core electrons 559 | ((l, # l=-1 for UL, l>=0 for Ul to indicate |l> 0: # to be fixed!! for Victor case 577 | 578 | ecp_num = 0 579 | ecp_max_ang_mom_plus_1 = [] 580 | ecp_z_core = [] 581 | ecp_nucleus_index = [] 582 | ecp_ang_mom = [] 583 | ecp_coefficient = [] 584 | ecp_exponent = [] 585 | ecp_power = [] 586 | 587 | for nuc_index, (chemical_symbol, atom_symbol) in enumerate( 588 | zip(chemical_symbol_list, atom_symbol_list) 589 | ): 590 | 591 | # atom_symbol is superior to atom_pure_symbol!! 592 | try: 593 | z_core, ecp_list = mol._ecp[atom_symbol] 594 | except KeyError: 595 | z_core, ecp_list = mol._ecp[chemical_symbol] 596 | 597 | # ecp zcore 598 | ecp_z_core.append(z_core) 599 | 600 | # max_ang_mom 601 | max_ang_mom = max([ecp[0] for ecp in ecp_list]) # this is lmax, right? 602 | if max_ang_mom == -1: 603 | # special case!! H and He. 604 | # PySCF database does not define the ul-s part for them. 605 | max_ang_mom = 0 606 | max_ang_mom_plus_1 = 1 607 | else: 608 | max_ang_mom_plus_1 = max_ang_mom + 1 609 | ecp_max_ang_mom_plus_1.append(max_ang_mom_plus_1) 610 | 611 | for ecp in ecp_list: 612 | ang_mom = ecp[0] 613 | if ang_mom == -1: 614 | ang_mom = max_ang_mom_plus_1 615 | for r, exp_coeff_list in enumerate(ecp[1]): 616 | for exp_coeff in exp_coeff_list: 617 | exp, coeff = exp_coeff 618 | 619 | # store variables!! 620 | ecp_num += 1 621 | ecp_nucleus_index.append(nuc_index) 622 | ecp_ang_mom.append(ang_mom) 623 | ecp_coefficient.append(coeff) 624 | ecp_exponent.append(exp) 625 | ecp_power.append(r - 2) 626 | 627 | # special case!! H and He. 628 | # For the sake of clarity, here I put a dummy coefficient (0.0) 629 | # for the ul-s part here. 630 | ecp_num += 1 631 | ecp_nucleus_index.append(nuc_index) 632 | ecp_ang_mom.append(0) 633 | ecp_coefficient.append(0.0) 634 | ecp_exponent.append(1.0) 635 | ecp_power.append(0) 636 | 637 | # write to the trex file 638 | trexio.write_ecp_num(trexio_file, ecp_num) 639 | trexio.write_ecp_max_ang_mom_plus_1(trexio_file, ecp_max_ang_mom_plus_1) 640 | trexio.write_ecp_z_core(trexio_file, ecp_z_core) 641 | trexio.write_ecp_nucleus_index(trexio_file, ecp_nucleus_index) 642 | trexio.write_ecp_ang_mom(trexio_file, ecp_ang_mom) 643 | trexio.write_ecp_coefficient(trexio_file, ecp_coefficient) 644 | trexio.write_ecp_exponent(trexio_file, ecp_exponent) 645 | trexio.write_ecp_power(trexio_file, ecp_power) 646 | 647 | # close the TREX-IO file 648 | trexio_file.close() 649 | 650 | logger.info("Conversion to TREXIO is done.") 651 | 652 | 653 | def cli(): 654 | import argparse 655 | from logging import getLogger, StreamHandler, Formatter 656 | 657 | log_level = "INFO" 658 | logger = getLogger("pyscf-trexio") 659 | logger.setLevel(log_level) 660 | stream_handler = StreamHandler() 661 | stream_handler.setLevel(log_level) 662 | handler_format = Formatter("%(message)s") 663 | stream_handler.setFormatter(handler_format) 664 | logger.addHandler(stream_handler) 665 | 666 | # define the parser 667 | parser = argparse.ArgumentParser( 668 | epilog="From pyscf chk file to TREXIO file", 669 | usage="python pyscf_to_trexio.py -c \ 670 | pyscf_checkfile -o trexio_filename", 671 | formatter_class=argparse.RawDescriptionHelpFormatter, 672 | ) 673 | parser.add_argument( 674 | "-c", 675 | "--pyscf_checkfile", 676 | help="pyscf checkfile", 677 | type=str, 678 | required=True, 679 | ) 680 | parser.add_argument( 681 | "-o", 682 | "--trexio_filename", 683 | help="trexio filename", 684 | type=str, 685 | default="trexio.hdf5", 686 | ) 687 | parser.add_argument( 688 | "-b", 689 | "--back_end", 690 | help="trexio I/O back-end", 691 | type=str, 692 | default="hdf5", 693 | ) 694 | 695 | # parse the input values 696 | args = parser.parse_args() 697 | # parsed_parameter_dict = vars(args) 698 | 699 | pyscf_to_trexio( 700 | pyscf_checkfile=args.pyscf_checkfile, 701 | trexio_filename=args.trexio_filename, 702 | back_end=args.back_end 703 | ) 704 | 705 | 706 | if __name__ == "__main__": 707 | cli() 708 | -------------------------------------------------------------------------------- /src/trexio_tools/group_tools/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/trexio_tools/group_tools/ao.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import trexio 4 | import numpy as np 5 | from . import basis as trexio_basis 6 | 7 | def read(trexio_file): 8 | r = {} 9 | 10 | r["basis"] = trexio_basis.read(trexio_file) 11 | r["basis_old"] = trexio_basis.convert_to_old(r["basis"]) 12 | r["num"] = trexio.read_ao_num(trexio_file) 13 | r["shell"] = trexio.read_ao_shell(trexio_file) 14 | r["factor"] = trexio.read_ao_normalization(trexio_file) 15 | 16 | return r 17 | 18 | powers = [ 19 | [(0,0,0)], 20 | [(1,0,0), (0,1,0), (0,0,1)], 21 | [(2,0,0), (1,1,0), (1,0,1), (0,2,0), (0,1,1), (0,0,2)], 22 | [(3,0,0), (2,1,0), (2,0,1), (1,2,0), (1,1,1), (1,0,2), 23 | (0,3,0), (0,2,1), (0,1,2), (0,0,3)] 24 | ] 25 | 26 | 27 | def value(ao,r): 28 | """ 29 | Evaluates all the basis functions at R=(x,y,z) 30 | """ 31 | 32 | basis = ao["basis"] 33 | 34 | nucleus = basis["nucleus"] 35 | coord = nucleus["coord"] 36 | nucleus_num = nucleus["num"] 37 | 38 | basis_num = basis["shell_num"] 39 | prim_num = basis["prim_num"] 40 | shell_ang_mom = basis["shell_ang_mom"] 41 | shell_factor = basis["shell_factor"] 42 | shell_index = [ i for i in basis["shell_index"] ] 43 | 44 | # to reconstruct for compatibility with TREXIO < v.2.0.0 45 | basis_old = ao["basis_old"] 46 | nucleus_index = basis_old["nucleus_index"] 47 | nucleus_shell_num = basis_old["nucleus_shell_num"] 48 | shell_prim_index = basis_old["shell_prim_index"] 49 | shell_prim_num = basis_old["shell_prim_num"] 50 | 51 | coefficient = basis["coefficient"] * basis["prim_factor"] 52 | exponent = basis["exponent"] 53 | 54 | norm = ao["factor"] 55 | 56 | # Compute all primitives and powers 57 | prims = np.zeros(prim_num) 58 | pows = [ 0. for i in range(basis_num) ] 59 | 60 | for i_nucl in range(nucleus_num): 61 | 62 | i_shell = nucleus_index[i_nucl] 63 | i_prim = shell_prim_index[i_shell] 64 | istart = i_prim 65 | 66 | dr = r - coord[i_nucl] 67 | r2 = dr[0]*dr[0] + dr[1]*dr[1] + dr[2]*dr[2] 68 | 69 | try: 70 | i_shell_end = nucleus_index[i_nucl+1] 71 | i_prim = shell_prim_index[i_shell_end] 72 | iend = i_prim 73 | except IndexError: 74 | iend = prim_num 75 | i_shell_end = basis_num 76 | 77 | old = None 78 | for i in range(i_shell,i_shell_end): 79 | if shell_ang_mom[i] != old: 80 | old = shell_ang_mom[i] 81 | x = np.array([ np.power(dr, p) for p in powers[old] ]) 82 | x = np.prod(x,axis=1) 83 | pows[i] = x 84 | 85 | for iprim in range(istart,iend): 86 | f = shell_factor[ shell_index[iprim] ] 87 | prims[iprim] = coefficient[iprim] * np.exp(-exponent[iprim]*r2) * f 88 | 89 | # Compute contractions 90 | rr = np.zeros(basis_num) 91 | for i_nucl in range(nucleus_num): 92 | for i in range(nucleus_shell_num[i_nucl]): 93 | i_shell = nucleus_index[i_nucl] + i 94 | n_prim = shell_prim_num[i_shell] 95 | i_prim = shell_prim_index[i_shell] 96 | rr[i_shell] = sum(prims[i_prim:i_prim+n_prim]) 97 | 98 | result = np.concatenate( [ rr[i] * p for i,p in enumerate(pows) ] ) 99 | 100 | return result * norm 101 | 102 | -------------------------------------------------------------------------------- /src/trexio_tools/group_tools/basis.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import trexio 4 | import numpy as np 5 | from . import nucleus 6 | 7 | def read(trexio_file): 8 | r = {} 9 | 10 | r["nucleus"] = nucleus.read(trexio_file) 11 | 12 | r["type"] = trexio.read_basis_type(trexio_file) 13 | r["shell_num"] = trexio.read_basis_shell_num(trexio_file) 14 | r["nucleus_index"] = trexio.read_basis_nucleus_index(trexio_file) 15 | r["shell_ang_mom"] = trexio.read_basis_shell_ang_mom(trexio_file) 16 | r["shell_factor"] = trexio.read_basis_shell_factor(trexio_file) 17 | if r["type"] == "Gaussian": 18 | r["shell_index"] = trexio.read_basis_shell_index(trexio_file) 19 | r["prim_num"] = trexio.read_basis_prim_num(trexio_file) 20 | r["exponent"] = trexio.read_basis_exponent(trexio_file) 21 | r["coefficient"] = trexio.read_basis_coefficient(trexio_file) 22 | r["prim_factor"] = trexio.read_basis_prim_factor(trexio_file) 23 | elif r["type"] == "Numerical": 24 | r["nao_grid_start"] = trexio.read_basis_nao_grid_start(trexio_file) 25 | r["nao_grid_size"] = trexio.read_basis_nao_grid_size(trexio_file) 26 | r["interpolator"] = trexio.read_basis_interpolator_phi(trexio_file) 27 | r["nao_grid_radius"] = trexio.read_basis_nao_grid_radius(trexio_file) 28 | 29 | return r 30 | 31 | 32 | def convert_to_old(basis: dict) -> dict: 33 | """Convert the new basis set format into the old one (<2.0.0).""" 34 | 35 | basis_old = {} 36 | # The quantities below did not change in v.2.0.0 37 | basis_old["type"] = basis["type"] 38 | basis_old["prim_num"] = basis["prim_num"] 39 | basis_old["shell_ang_mom"] = basis["shell_ang_mom"] 40 | basis_old["shell_factor"] = basis["shell_factor"] 41 | basis_old["exponent"] = basis["exponent"] 42 | basis_old["coefficient"] = basis["coefficient"] 43 | basis_old["prim_factor"] = basis["prim_factor"] 44 | # basis_num has been renamed into basis_shell_num 45 | basis_old["num"] = basis["shell_num"] 46 | # The per-nucleus and per-shell lists below have to be reconstructed from the 47 | # `nucleus_index` and `shell_index` maps, respectively, introduced in v.2.0.0 48 | # Save the data in the old format (index of the first shell and No of shells per atom) 49 | l1, l2 = map_to_lists(basis["nucleus_index"], basis["nucleus"]["num"]) 50 | basis_old["nucleus_index"] = l1 51 | basis_old["nucleus_shell_num"] = l2 52 | # Same for primitives per shell 53 | l3, l4 = map_to_lists(basis["shell_index"], basis["shell_num"]) 54 | basis_old["shell_prim_index"] = l3 55 | basis_old["shell_prim_num"] = l4 56 | 57 | return basis_old 58 | 59 | 60 | def map_to_lists(map: list, dim: int) -> tuple: 61 | """Convert long map into two short ones (with index and number of elements per instance (e.g. atom), respectively).""" 62 | 63 | from collections import Counter 64 | 65 | index_per_instance = [] 66 | instances_done = [] 67 | for i, inst in enumerate(map): 68 | if not inst in instances_done: 69 | index_per_instance.append(i) 70 | instances_done.append(inst) 71 | 72 | n_per_instance = Counter(map) 73 | num_per_instance = [ n_per_instance[j] for j in range(dim) ] 74 | 75 | if(len(index_per_instance) != len(num_per_instance)): 76 | raise Exception(f"Inconsistent dimensions of output arrays: {len(index_per_instance)} != {len(num_per_instance)}") 77 | #print(map, "\n", index_per_instance, "\n", num_per_instance) 78 | 79 | return (index_per_instance, num_per_instance) 80 | 81 | 82 | def lists_to_map(indices: list, numbers: list) -> list: 83 | """Convert two lists (with index and number of elements per instance like atom) into one big mapping list.""" 84 | 85 | if(len(indices) != len(numbers)): 86 | raise Exception(f"Inconsistent dimensions of input arrays: {len(indices)} != {len(numbers)}") 87 | 88 | map = [] 89 | for i, _ in enumerate(indices): 90 | for _ in range(numbers[i]): 91 | map.append(i) 92 | #print(indices, "\n", numbers, "\n", map) 93 | 94 | return map 95 | -------------------------------------------------------------------------------- /src/trexio_tools/group_tools/check_basis.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import trexio 4 | import numpy as np 5 | from . import nucleus as trexio_nucleus 6 | from . import basis as trexio_basis 7 | from . import ao as trexio_ao 8 | 9 | def run(trexio_file, n_points): 10 | """ 11 | Computes numerically the overlap matrix in the AO basis and compares it to 12 | the matrix stored in the file. 13 | """ 14 | 15 | print(trexio.read_basis_type(trexio_file)) 16 | if trexio.read_basis_type(trexio_file) == "Numerical": 17 | from . import nao as trexio_ao 18 | else: 19 | from . import ao as trexio_ao 20 | ao = trexio_ao.read(trexio_file) 21 | basis = ao["basis"] 22 | nucleus = basis["nucleus"] 23 | assert basis["type"] == "Gaussian" or basis["type"] == "Numerical" 24 | 25 | rmin = np.array( list([ np.min(nucleus["coord"][:,a]) for a in range(3) ]) ) 26 | rmax = np.array( list([ np.max(nucleus["coord"][:,a]) for a in range(3) ]) ) 27 | 28 | shift = np.array([8.,8.,8.]) 29 | linspace = [ None for i in range(3) ] 30 | step = [ None for i in range(3) ] 31 | for a in range(3): 32 | linspace[a], step[a] = np.linspace(rmin[a]-shift[a], rmax[a]+shift[a], num=n_points, retstep=True) 33 | 34 | print("Integration steps:", step) 35 | dv = step[0]*step[1]*step[2] 36 | ao_num = ao["num"] 37 | 38 | point = [] 39 | for x in linspace[0]: 40 | for y in linspace[1]: 41 | for z in linspace[2]: 42 | point += [ [x, y, z] ] 43 | point = np.array(point) 44 | point_num = len(point) 45 | 46 | if trexio.has_ao_1e_int_overlap(trexio_file): 47 | S_ex = trexio.read_ao_1e_int_overlap(trexio_file) 48 | else: 49 | S_ex = np.zeros((ao_num,ao_num)) 50 | 51 | 52 | try: 53 | import qmckl 54 | 55 | trexio_filename = trexio_file.filename 56 | context = qmckl.context_create() 57 | qmckl.trexio_read(context, trexio_filename) 58 | 59 | qmckl.set_point(context, 'N', point_num, np.reshape(point, (point_num*3))) 60 | chi = qmckl.get_ao_basis_ao_value(context, point_num*ao_num) 61 | chi = np.reshape( chi, (point_num,ao_num) ) 62 | S = chi.T @ chi * dv 63 | 64 | except ImportError: 65 | 66 | chi = [] 67 | for xyz in point: 68 | chi += [ trexio_ao.value(ao, np.array(xyz)) ] 69 | 70 | chi = np.reshape( chi, (point_num,ao_num) ) 71 | S = chi.T @ chi * dv 72 | 73 | print() 74 | 75 | 76 | for i in range(ao_num): 77 | for j in range(i,ao_num): 78 | print("%3d %3d %15f %15f"%(i,j,S[i][j],S_ex[i,j])) 79 | S_diff = S - S_ex 80 | print("Norm of the error: %f"%(np.linalg.norm(S_diff))) 81 | 82 | print("Diagonal entries:") 83 | for i in range(ao_num): 84 | print("%3d %15f"%(i,S[i][i])) 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/trexio_tools/group_tools/check_mos.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import trexio 4 | import numpy as np 5 | from . import nucleus as trexio_nucleus 6 | from . import basis as trexio_basis 7 | from . import ao as trexio_ao 8 | from . import mo as trexio_mo 9 | 10 | def run(trexio_file, n_points): 11 | 12 | """ 13 | Computes numerically the overlap matrix in the AO basis and compares it to 14 | the matrix stored in the file. 15 | """ 16 | 17 | mo = trexio_mo.read(trexio_file) 18 | ao = mo["ao"] 19 | basis = ao["basis"] 20 | nucleus = basis["nucleus"] 21 | assert basis["type"] == "Gaussian" 22 | 23 | rmin = np.array( list([ np.min(nucleus["coord"][:,a]) for a in range(3) ]) ) 24 | rmax = np.array( list([ np.max(nucleus["coord"][:,a]) for a in range(3) ]) ) 25 | 26 | shift = np.array([8.,8.,8.]) 27 | linspace = [ None for i in range(3) ] 28 | step = [ None for i in range(3) ] 29 | for a in range(3): 30 | linspace[a], step[a] = np.linspace(rmin[a]-shift[a], rmax[a]+shift[a], 31 | num=n_points, retstep=True) 32 | 33 | print("Integration steps:", step) 34 | dv = step[0]*step[1]*step[2] 35 | mo_num = mo["num"] 36 | 37 | point = [] 38 | for x in linspace[0]: 39 | #print(".",end='',flush=True) 40 | for y in linspace[1]: 41 | for z in linspace[2]: 42 | point += [ [x, y, z] ] 43 | point = np.array(point) 44 | point_num = len(point) 45 | 46 | 47 | try: 48 | import qmckl 49 | 50 | context = qmckl.context_create() 51 | trexio_filename = trexio_file.filename 52 | qmckl.trexio_read(context, trexio_filename) 53 | 54 | qmckl.set_point(context, 'N', point_num, np.reshape(point, (point_num*3))) 55 | chi = qmckl.get_mo_basis_mo_value(context, point_num*mo_num) 56 | 57 | except ImportError: 58 | 59 | chi = [] 60 | for xyz in point: 61 | chi += [ trexio_mo.value(mo, np.array(xyz)) ] 62 | 63 | chi = np.reshape( chi, (point_num,mo_num) ) 64 | S = chi.T @ chi * dv 65 | 66 | print() 67 | 68 | S_ex = np.eye(mo_num) 69 | S_diff = S - S_ex 70 | 71 | for i in range(mo_num): 72 | for j in range(i,mo_num): 73 | print("%3d %3d %15f %15f"%(i,j,S[i][j],S_ex[i,j])) 74 | 75 | print ("Norm of the error: %e"%(np.linalg.norm(S_diff))) 76 | #print(S_diff) 77 | 78 | -------------------------------------------------------------------------------- /src/trexio_tools/group_tools/determinant.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def to_determinant_list(orbital_list: list, int64_num: int) -> list: 4 | """ 5 | Convert a list of occupied orbitals from the `orbital_list` 6 | into a list of Slater determinants (in their bit string representation). 7 | 8 | Orbitals in the `orbital_list` should be 0-based, namely the lowest orbital has index 0, not 1. 9 | 10 | int64_num is the number of 64-bit integers needed to represent a Slater determinant bit string. 11 | It depends on the number of molecular orbitals as follows: int64_num = int((mo_num-1)/64) + 1 12 | """ 13 | 14 | if not isinstance(orbital_list, list): 15 | raise TypeError(f"orbital_list should be a list, not {type(orbital_list)}") 16 | 17 | det_list = [] 18 | bitfield = 0 19 | shift = 0 20 | 21 | # since orbital indices are 0-based but the code below works for 1-based --> increment the input indices by +1 22 | orb_list_upshifted = [ orb+1 for orb in orbital_list] 23 | 24 | # orbital list has to be sorted in increasing order for the bitfields to be set correctly 25 | orb_list_sorted = sorted(orb_list_upshifted) 26 | 27 | for orb in orb_list_sorted: 28 | 29 | if orb-shift > 64: 30 | # this removes the 0 bit from the beginning of the bitfield 31 | bitfield = bitfield >> 1 32 | # append a bitfield to the list 33 | det_list.append(bitfield) 34 | bitfield = 0 35 | 36 | modulo = int((orb-1)/64) 37 | shift = modulo*64 38 | bitfield |= (1 << (orb-shift)) 39 | 40 | # this removes the 0 bit from the beginning of the bitfield 41 | bitfield = bitfield >> 1 42 | det_list.append(bitfield) 43 | #print('Popcounts: ', [bin(d).count('1') for d in det_list) 44 | #print('Bitfields: ', [bin(d) for d in det_list]) 45 | 46 | bitfield_num = len(det_list) 47 | if bitfield_num > int64_num: 48 | raise Exception(f'Number of bitfields {bitfield_num} cannot be more than the int64_num {int64_num}.') 49 | if bitfield_num < int64_num: 50 | for _ in range(int64_num - bitfield_num): 51 | print("Appending an empty bitfield.") 52 | det_list.append(0) 53 | 54 | return det_list 55 | 56 | -------------------------------------------------------------------------------- /src/trexio_tools/group_tools/mo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import trexio 4 | import numpy as np 5 | from . import ao as trexio_ao 6 | 7 | def read(trexio_file): 8 | r = {} 9 | 10 | r["ao"] = trexio_ao.read(trexio_file) 11 | r["num"] = trexio.read_mo_num(trexio_file) 12 | r["coefficient"] = trexio.read_mo_coefficient(trexio_file) 13 | 14 | # if trexio.has_mo_type(trexio_file): 15 | # r["type"] = trexio.read_mo_type(trexio_file) 16 | # if trexio.has_mo_class(trexio_file): 17 | # r["class"] = trexio.read_mo_class(trexio_file) 18 | # if trexio.has_mo_symmetry(trexio_file): 19 | # r["symmetry"] = trexio.read_mo_symmetry(trexio_file) 20 | # if trexio.has_mo_occupation(trexio_file): 21 | # r["occupation"] = trexio.read_mo_occupation(trexio_file) 22 | 23 | return r 24 | 25 | 26 | def value(mo, r): 27 | """ 28 | Evaluates all the MOs at R=(x,y,z) 29 | """ 30 | 31 | ao = mo["ao"] 32 | ao_value = trexio_ao.value(ao, r) 33 | coef = mo["coefficient"] 34 | return coef @ ao_value 35 | -------------------------------------------------------------------------------- /src/trexio_tools/group_tools/nao.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Script to numerically calculate the overlap integrals for numerical 5 | orbitals of the FHIaims-type 6 | 7 | Written by Johannes Günzl, TU Dresden 2023 8 | """ 9 | 10 | import trexio 11 | import numpy as np 12 | from scipy.special import sph_harm, factorial 13 | 14 | from . import basis as trexio_basis 15 | 16 | ao_exponents_l_cart = [] 17 | # [[0, 0, 0]], 18 | # [[1, 0, 0], [0, 1, 0], [0, 0, 1]], 19 | # [[2, 0, 0], [1, 1, 0], [1, 0, 1], [0, 2, 0], [0, 1, 1], [0, 0, 2]] etc 20 | 21 | # Generate l-exponents for cartesian orbitals 22 | for l in range(10): 23 | sublist = [] 24 | for x in range(l + 1): 25 | for y in range(l - x + 1): 26 | sublist.append([x, y, l - x - y]) 27 | sublist.reverse() 28 | ao_exponents_l_cart.append(sublist) 29 | 30 | 31 | def read(trexio_file): 32 | r = {} 33 | 34 | r["basis"] = trexio_basis.read(trexio_file) 35 | r["num"] = trexio.read_ao_num(trexio_file) 36 | r["shell"] = trexio.read_ao_shell(trexio_file) 37 | r["factor"] = trexio.read_ao_normalization(trexio_file) 38 | r["cartesian"] = trexio.read_ao_cartesian(trexio_file) 39 | 40 | # Since this varibale is not used for spherical harmonics, this is fine 41 | ao_exponents_l = ao_exponents_l_cart 42 | 43 | ao_num = r["num"] 44 | basis = r["basis"] 45 | ao_shell = r["shell"] 46 | shell_ang_mom = basis["shell_ang_mom"] 47 | 48 | ao_exponents = np.zeros((ao_num, 3), dtype=float) 49 | same_shell_cnt = 0 50 | last_shell = -1 51 | 52 | for i in range(ao_num): 53 | curr_shell = ao_shell[i] 54 | if curr_shell != last_shell: 55 | same_shell_cnt = -1 56 | last_shell = curr_shell 57 | same_shell_cnt += 1 58 | l = shell_ang_mom[curr_shell] 59 | ao_exponents[i] = ao_exponents_l[l][same_shell_cnt] 60 | 61 | r["ao_exponents"] = ao_exponents 62 | 63 | return r 64 | 65 | def shell_to_ao(ao, ao_ind, r, shell_rad, m): 66 | ao_shell = ao["shell"] 67 | basis = ao["basis"] 68 | shell_ang_mom = basis["shell_ang_mom"] 69 | nucleus_index = basis["nucleus_index"] 70 | nucleus_coord = basis["nucleus"]["coord"] 71 | ao_norms = ao["factor"] 72 | 73 | l = shell_ang_mom[ao_shell[ao_ind]] 74 | nuc_coords = nucleus_coord[nucleus_index[ao_shell[ao_ind]]] 75 | 76 | dx = r[0] - nuc_coords[0] 77 | dy = r[1] - nuc_coords[1] 78 | dz = r[2] - nuc_coords[2] 79 | 80 | dr = np.sqrt(dx**2 + dy**2 + dz**2) 81 | if ao["cartesian"] == 1: 82 | exps = ao["ao_exponents"][ao_ind] 83 | angle_part = dx**exps[0] * dy**exps[1] * dz**exps[2] * dr**-l 84 | ret = shell_rad * angle_part * ao_norms[ao_ind] 85 | else: 86 | theta = np.arccos(dz/dr) 87 | phi = np.sign(dy)*np.arccos(dx/(dx**2+dy**2)**(0.5)) 88 | 89 | # Convert from Gamess convetion to FHI-aims convention (each radial 90 | # function is normalized with an s-orbital) since it is more 91 | # convenient here 92 | l_factor = [1, 1, 2, 2, 8, 8, 16, 16, 128, 128, 256] 93 | l_factor = np.sqrt(np.array([ 94 | (2*l + 1) / l_factor[l]**2 for l in range(11) 95 | ]) * (1/np.pi))/2 96 | 97 | shell_rad /= l_factor[l] 98 | 99 | angle_part = sph_harm(np.abs(m), l, phi, theta) 100 | if m == 0: 101 | angle_part = np.real(angle_part) 102 | if m < 0: 103 | angle_part = np.sqrt(2)*(-1)**m*np.imag(angle_part) 104 | if m > 0: 105 | angle_part = np.sqrt(2)*(-1)**m*np.real(angle_part) 106 | 107 | # ao_norm is handled by scipy 108 | ret = shell_rad * angle_part 109 | 110 | return ret 111 | 112 | def value(ao,r): 113 | """ 114 | Evaluates all the basis functions at R=(x,y,z) 115 | """ 116 | 117 | basis = ao["basis"] 118 | ao_num = ao["num"] 119 | 120 | nucleus = basis["nucleus"] 121 | coord = nucleus["coord"] 122 | nucleus_num = nucleus["num"] 123 | 124 | basis_num = basis["shell_num"] 125 | shell_ang_mom = basis["shell_ang_mom"] 126 | 127 | nucleus_index = basis["nucleus_index"] 128 | 129 | nao_grid_start = basis["nao_grid_start"] 130 | nao_grid_size = basis["nao_grid_size"] 131 | nao_grid_r = basis["nao_grid_radius"] 132 | interpolator = basis["interpolator"] 133 | shell_factor = basis["shell_factor"] 134 | norm = ao["factor"] 135 | ao_shell = ao["shell"] 136 | 137 | amplitudes = trexio.evaluate_nao_radial_all(nucleus_index, coord, 138 | nao_grid_start, nao_grid_size, nao_grid_r, interpolator, shell_factor, r) 139 | 140 | ao_amp = np.zeros(ao_num, dtype=float) 141 | last_shell = ao_shell[0] 142 | n = 0 # Index of current ao within current shell 143 | for a in range(ao_num): 144 | curr_shell = ao_shell[a] 145 | if curr_shell != last_shell: 146 | last_shell = curr_shell 147 | n = 0 148 | 149 | m = (n+1)//2 * (2*(n % 2) - 1) 150 | ao_amp[a] = shell_to_ao(ao, a, r, amplitudes[curr_shell], m) 151 | n += 1 152 | 153 | #print(r, ao_amp) 154 | 155 | return ao_amp 156 | 157 | -------------------------------------------------------------------------------- /src/trexio_tools/group_tools/nucleus.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import trexio 4 | import numpy as np 5 | 6 | def read(trexio_file): 7 | r = {} 8 | 9 | r["num"] = trexio.read_nucleus_num(trexio_file) 10 | r["charge"] = trexio.read_nucleus_charge(trexio_file) 11 | r["coord"] = trexio.read_nucleus_coord(trexio_file) 12 | r["label"] = trexio.read_nucleus_label(trexio_file) 13 | 14 | return r 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/trexio_tools/trexio_run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Set of tools to interact with trexio files. 4 | 5 | Usage: 6 | trexio check-basis [-n N_POINTS] [-b BACK_END] TREXIO_FILE 7 | trexio check-mos [-n N_POINTS] [-b BACK_END] TREXIO_FILE 8 | trexio convert-to -t TYPE -o OUTPUT_FILE [-y SPIN_ORDER] TREXIO_FILE 9 | trexio convert-from -t TYPE -i INPUT_FILE [-b BACK_END] [-S STATE_SUFFIX ] [-x MO_TYPE] [-m MULTIPLICITY] [-w] TREXIO_FILE 10 | trexio convert-backend -i INPUT_FILE -o OUTPUT_FILE -b BACK_END -j TREX_JSON_FILE [-s BACK_END_FROM] [-w] 11 | trexio (-h | --help) 12 | 13 | Options: 14 | -h, --help Print help message. 15 | -n, --n_points=N_POINTS Number of integration points. [default: 81] 16 | -i, --input=INPUT_FILE Name of the input file. 17 | -o, --output=OUTPUT_FILE Name of the output file. 18 | -b, --back_end=BACK_END [hdf5 | text | auto] The TREXIO back end. [default: hdf5] 19 | -s, --back_end_from=BACK_END [hdf5 | text | auto] The input TREXIO back end. [default: auto] 20 | -S, --state_suffix=STATE_SUFFIX Suffix for the generated TREXIO file for a multistate calculation conversion. [default: state] 21 | -m, --multiplicity=MULTIPLICITY Spin multiplicity for the Crystal converter. 22 | -j, --json=TREX_JSON_FILE TREX configuration file (in JSON format). 23 | -w, --overwrite Overwrite the output TREXIO file if it already exists. [default: True] 24 | -t, --type=TYPE [gaussian | gamess | pyscf | orca | crystal | fcidump | molden | cartesian | spherical ] File format. 25 | -x, --motype=MO_TYPE Type of the molecular orbitals. For example, GAMESS has RHF, MCSCF, GUGA, and Natural as possible MO types. 26 | -y, --spin_order=TYPE [block | interleave] How to organize spin orbitals when converting to FCIDUMP [default: block] 27 | """ 28 | 29 | from docopt import docopt 30 | import trexio 31 | import os 32 | 33 | 34 | def remove_trexio_file(filename:str, overwrite:bool) -> None: 35 | """Remove the TREXIO file/directory if it exists.""" 36 | if os.path.exists(filename): 37 | if overwrite: 38 | # dummy check 39 | if '*' in filename: 40 | raise ValueError(f'TREXIO filename {filename} contains * symbol. Are you sure?') 41 | # check that the file is actually TREXIO file 42 | try: 43 | is_trexio = False 44 | with trexio.File(filename, 'r', trexio.TREXIO_AUTO) as tfile: 45 | if trexio.has_metadata_package_version(tfile): 46 | is_trexio = True 47 | 48 | if is_trexio: os.system(f'rm -rf -- {filename}') 49 | 50 | except: 51 | raise Exception(f'Output file {filename} exists but it is not a TREXIO file. Are you sure?') 52 | else: 53 | raise Exception(f'Output file {filename} already exists but overwrite option is not provided. Consider using the `-w` CLI argument.') 54 | 55 | return 56 | 57 | 58 | def main(filename=None, args=None) -> None: 59 | """Main entry point""" 60 | 61 | if filename is None and args is None: 62 | args = docopt(__doc__) 63 | filename = args["TREXIO_FILE"] 64 | 65 | n_points = int(args["--n_points"]) if args["--n_points"] else 81 66 | 67 | overwrite = not str(args["--overwrite"]).lower() in ['false', '0'] 68 | 69 | if args["convert-backend"]: 70 | remove_trexio_file(args["--output"], overwrite) 71 | 72 | if args["convert-from"]: 73 | remove_trexio_file(args["TREXIO_FILE"], overwrite) 74 | 75 | if args["--back_end"]: 76 | if str(args["--back_end"]).lower() == "hdf5": 77 | back_end = trexio.TREXIO_HDF5 78 | elif str(args["--back_end"]).lower() == "text": 79 | back_end = trexio.TREXIO_TEXT 80 | elif str(args["--back_end"]).lower() == "auto": 81 | back_end = trexio.TREXIO_AUTO 82 | else: 83 | raise ValueError("Supported back ends: text, hdf5, auto.") 84 | else: 85 | if args["convert-backend"]: 86 | raise Exception("Missing argument for the target back end: specify --back_end or -b.") 87 | 88 | if args["--back_end_from"]: 89 | if str(args["--back_end_from"]).lower() == "hdf5": 90 | back_end_from = trexio.TREXIO_HDF5 91 | elif str(args["--back_end_from"]).lower() == "text": 92 | back_end_from = trexio.TREXIO_TEXT 93 | elif str(args["--back_end_from"]).lower() == "auto": 94 | back_end_from = trexio.TREXIO_AUTO 95 | else: 96 | raise ValueError("Supported options: text, hdf5, auto (default).") 97 | else: 98 | back_end_from = trexio.TREXIO_AUTO 99 | 100 | spin = int(args["--multiplicity"]) if args["--multiplicity"] else None 101 | 102 | if args["check-basis"]: 103 | trexio_file = trexio.File(filename, 'r', back_end=back_end) 104 | if trexio_file is None: 105 | raise IOError 106 | 107 | from .group_tools.check_basis import run 108 | run(trexio_file,n_points) 109 | 110 | elif args["check-mos"]: 111 | trexio_file = trexio.File(filename, 'r', back_end=back_end) 112 | if trexio_file is None: 113 | raise IOError 114 | 115 | from .group_tools.check_mos import run 116 | run(trexio_file,n_points) 117 | 118 | elif args["convert-from"]: 119 | from .converters.convert_from import run 120 | run(args["TREXIO_FILE"], args["--input"], args["--type"], back_end=back_end, spin=spin, motype=args["--motype"], state_suffix=args["--state_suffix"], 121 | overwrite=args["--overwrite"]) 122 | 123 | elif args["convert-to"]: 124 | from .converters.convert_to import run 125 | run(args["TREXIO_FILE"], args["--output"], args["--type"], args["--spin_order"]) 126 | 127 | elif args["convert-backend"]: 128 | from .converters.convert_back_end import run 129 | run( 130 | args["--input"], 131 | args["--output"], 132 | back_end_to=back_end, 133 | back_end_from=back_end_from, 134 | json_filename=args["--json"] 135 | ) 136 | 137 | else: 138 | pass 139 | 140 | 141 | if __name__ == '__main__': 142 | args = docopt(__doc__) 143 | filename = args["TREXIO_FILE"] 144 | main(filename, args) 145 | -------------------------------------------------------------------------------- /utilities/to_gamess_normalization.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from resultsFile.lib.basis import xyz_from_lm 4 | from trexio_tools.converters import cart_sphe 5 | import numpy as np 6 | 7 | 8 | def run(l): 9 | xyz_from_lm_results = [[0]+ list(xyz_from_lm(l,0))] 10 | for m in range(1,l+1): 11 | xyz_from_lm_results.append( [2*m-1] + list(xyz_from_lm(l,m)) ) 12 | xyz_from_lm_results.append( [2*m] + list(xyz_from_lm(l,-m)) ) 13 | 14 | 15 | # Find the ordering of xyz functions 16 | order = {} 17 | for _, p, _ in xyz_from_lm_results: 18 | for x in p: 19 | order[x] = 0 20 | lst = [ x for x in order.keys()] 21 | lst.sort() 22 | lst.reverse() 23 | for i, p in enumerate(lst): 24 | order[p] = i 25 | 26 | ref = cart_sphe.data[l] 27 | new = np.array(cart_sphe.data[l]) 28 | new -= new 29 | for i, p, c in xyz_from_lm_results: 30 | for p, c in zip(p,c): 31 | new[order[p],i] = c 32 | 33 | new = new/(ref+1.e-32) 34 | res = np.array(new[:,0]) 35 | for i in range(new.shape[0]): 36 | for j in range(new.shape[1]): 37 | res[i] = max(res[i], new[i,j]) 38 | return list(res) 39 | 40 | 41 | for l in range(11): 42 | print(l, run(l)) 43 | --------------------------------------------------------------------------------