Giter Club home page Giter Club logo

xtb-python's Introduction

Python API for the extended tight binding program

Conda Version License Documentation Status LGTM Codecov

This repository hosts the Python API for the extended tight binding (xtb) program.

Warning ⚠️ : xtb-python is no longer in active development. We recommend using tblite instead.

The idea of this project is to provide the xtb API for Python without requiring an additional xtb installation.

Installation

Depending on what you plan to do with xtb-python there are two recommended ways to install.

  • If you plan to use this project in your workflows, follow the Conda Installation section.
  • If you plan to develop on this project, proceed with the Build from Source section.

For more details visit the documentation.

Conda Installation

Installing xtb-python from the conda-forge channel can be achieved by adding conda-forge to your channels with:

conda config --add channels conda-forge

Once the conda-forge channel has been enabled, xtb-python can be installed with:

conda install xtb-python

It is possible to list all of the versions of xtb-python available on your platform with:

conda search xtb-python --channel conda-forge

Build from Source

The project is build with meson, the exact dependencies are defined by the xtb project, in summary it requires a Fortran and a C compiler as well as a linear algebra backend. Make yourself familiar with building xtb first!

Additionally this project requires a development version of Python installed. Also ensure that you have the numpy and cffi packages installed, configure the build of the extension with.

All steps to build the project are automated using

pip install .

To pass options to the meson build of xtb use --config-setting setup-args="-Dxtb-6.5.1:la_backend=openblas" to set for example the linear algebra backend to OpenBLAS.

Contributing

Contributions to this open source project are very welcome. Before starting, review our contributing guidelines first, please.

License

xtb-python is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

xtb-python is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See the GNU Lesser General Public License for more details.

xtb-python's People

Contributors

awvwgk avatar bwvdg avatar coltonbh avatar hppritcha avatar jthorton avatar lgtm-migrator avatar mtolston avatar sneves20 avatar tybalduf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

xtb-python's Issues

ASE support for net charge

Describe the bug

Directly using XTB-python interface the charge= parameter can be passed, but employing the same approach with ASE/XTB, charge doesn't get propagated

Ie, this works for charge=0 and charge=1 and changes energy accordingly

calc = Calculator(Param.GFN2xTB, mol.get_atomic_numbers(), mol.get_scaled_positions(), charge=1)
res = calc.singlepoint()
print('energy', res.get_energy())

However, this doesn't remember the charge and always sets charge to 0:

mol2 = read('qca_seed10.xyz') 
mol2.set_calculator(XTB(method="GFN2-xTB", charge=1))
print('pe', mol2.get_potential_energy())

To Reproduce

unzip the file and run the script
f.zip

  1. xtb.version is 20.1
  2. output:
direct calc energy 71.23435304058115
direct calc energy 71.54337595108338
energy before conversion -63.89323100198211
ase/xtb pe -1738.623373139004
energy before conversion -63.89323100198211
ase/xtb pe -1738.623373139004

Expected behaviour

charge affecting the final energy when ase/xtb is used

The issue seems to be in the XTB class :
_charge = self.atoms.get_initial_charges().sum()

Thanks!

Periodic support in ASE calculator

Hello,

I was trying to use the ASE calculator in PBC with XTB using the GFN0-xTB parameters, which seem to work OK for the systems that I am studying.

The ASE calculator is, as far as I understand, not supporting such info because the cell and pbc info in the Atoms object are not parsed, but should be quite straightforward to pass to the underlying Calculator that connects with the XTB API. Actually, this seems to work if I do it directly with a simple wrapper.

I wondered why (if there is a reason) this has not been done yet. I might do it myself, which I guess would only require a bunch of pure python in the ASE calculator file.

I might also want to have a verbosity flag passed to the ASE calculator so that it is not actually mute, because sometimes I might care about the outputs of the XTB part. Again, does not seem to be a lot of work and I could do it myself by passing a verbosity attribute in the Atoms object. Does that seem reasonable?

In any case, thank you and the group for this mighty, mighty effort.

Different default parameters between xtb python and xtb

Describe the bug

Not sue this is really a bug, you github leaves me no choice ;)
I ran xtb with default parameters (charge 0) on the input molecule here:
out.sdf.zip

xtb out.sdf --charge 0

When I run xtb through python the python bindings using the sample documentation

calc = Calculator(Param.GFN2xTB, atomic_numbers, positions,charge=0)
res = calc.singlepoint()
return(res.get_energy())

I get significantly different energies.

I though that GFN2xTB is also used by default by the xtb binary so I expected similar results. Could you indicate which parameters to use in the python bindings to reproduce results from the command line version?

To Reproduce

CLI:
xtb out.sdf --charge 0

Output:

xtb data/docking/out.sdf --charge 0 
      -----------------------------------------------------------      
     |                   =====================                   |     
     |                           x T B                           |     
     |                   =====================                   |     
     |                         S. Grimme                         |     
     |          Mulliken Center for Theoretical Chemistry        |     
     |                    University of Bonn                     |     
      -----------------------------------------------------------      

   * xtb version 6.3.1 (conda-forge) compiled by '[email protected]' on 

   xtb is free software: you can redistribute it and/or modify it under
   the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   
   xtb is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.
   
   Cite this work as:
   * S. Grimme, C. Bannwarth, P. Shushkov, J. Chem. Theory Comput., 2017,
     13, 1989-2009. DOI: 10.1021/acs.jctc.7b00118
   * C. Bannwarth, S. Ehlert and S. Grimme., J. Chem. Theory Comput., 2019,
     15, 1652-1671. DOI: 10.1021/acs.jctc.8b01176
   * P. Pracht, E. Caldeweyher, S. Ehlert, S. Grimme, ChemRxiv, 2019, preprint.
     DOI: 10.26434/chemrxiv.8326202.v1
   
   for GFN-FF:
   * S. Spicher and S. Grimme, Angew. Chem. Int. Ed., 2020,
     DOI: 10.1002/anie.202004239
   
   for DFT-D4:
   * E. Caldeweyher, C. Bannwarth and S. Grimme, J. Chem. Phys., 2017,
     147, 034112. DOI: 10.1063/1.4993215
   * E. Caldeweyher, S. Ehlert, A. Hansen, H. Neugebauer, S. Spicher,
     C. Bannwarth and S. Grimme, J. Chem. Phys., 2019, 150, 154122.
     DOI: 10.1063/1.5090222
   
   for sTDA-xTB:
   * S. Grimme and C. Bannwarth, J. Chem. Phys., 2016, 145, 054103.
     DOI: 10.1063/1.4959605
   
   in the mass-spec context:
   * V. Asgeirsson, C. Bauer and S. Grimme, Chem. Sci., 2017, 8, 4879.
     DOI: 10.1039/c7sc00601b
   * J. Koopman and S. Grimme, ACS Omega 2019, 4, 12, 15120-15133.
     DOI: 10.1021/acsomega.9b02011
   
   for metadynamics refer to:
   * S. Grimme, J. Chem. Theory Comput., 2019, 155, 2847-2862
     DOI: 10.1021/acs.jctc.9b00143
   
   with help from (in alphabetical order)
   C. Bannwarth, F. Bohle, G. Brandenburg, E. Caldeweyher, M. Checinski,
   S. Dohm, S. Ehlert, S. Ehrlich, F. März, H. Neugebauer, J. Pisarek,
   P. Pracht, P. Shushkov, and S. Spicher.
   
 * started run on 2020/06/11 at 15:52:08.342     

           -------------------------------------------------
          |                Calculation Setup                |
           -------------------------------------------------

          program call               : xtb data/docking/out.sdf --charge 0
          coordinate file            : data/docking/out.sdf
          omp threads                :                    12
          number of atoms            :                    23
          number of electrons        :                    99
          charge                     :                     0
          spin                       :                   0.5
          first test random number   :      0.12034868984915

   ID    Z sym.   atoms
    1    6 C      1-4, 6, 8, 9, 11, 12, 15-21, 23
    2    7 N      5, 7, 10, 13, 14
    3    8 O      22

           -------------------------------------------------
          |                 G F N 2 - x T B                 |
           -------------------------------------------------

        Reference                      10.1021/acs.jctc.8b01176
      * Hamiltonian:
        H0-scaling (s, p, d)           1.850000    2.230000    2.230000
        zeta-weighting                 0.500000
      * Dispersion:
        s8                             2.700000
        a1                             0.520000
        a2                             5.000000
        s9                             5.000000
      * Repulsion:
        kExp                           1.500000    1.000000
        rExp                           1.000000
      * Coulomb:
        alpha                          2.000000
        third order                    shell-resolved
        anisotropic                    true
        a3                             3.000000
        a5                             4.000000
        cn-shift                       1.200000
        cn-exp                         4.000000
        max-rad                        5.000000

q/qsh data taken from xtbrestart
CAMM data taken from xtbrestart

          ...................................................
          :                      SETUP                      :
          :.................................................:
          :  # basis functions                  92          :
          :  # atomic orbitals                  92          :
          :  # shells                           46          :
          :  # electrons                        99          :
          :  max. iterations                   250          :
          :  Hamiltonian                  GFN2-xTB          :
          :  restarted?                       true          :
          :  GBSA solvation                  false          :
          :  PC potential                    false          :
          :  electronic temp.          300.0000000     K    :
          :  accuracy                    1.0000000          :
          :  -> integral cutoff          0.2500000E+02      :
          :  -> integral neglect         0.1000000E-07      :
          :  -> SCF convergence          0.1000000E-05 Eh   :
          :  -> wf. convergence          0.1000000E-03 e    :
          :  Broyden damping             0.4000000          :
          ...................................................

 iter      E             dE          RMSdq      gap      omega  full diag
   1    -54.4329000 -0.544329E+02  0.131E-04    0.02       0.0  T
   2    -54.4328991  0.933692E-06  0.437E-03    0.02       4.8  T
   3    -54.4328996 -0.532692E-06  0.302E-03    0.02       6.9  T
   4    -54.4329000 -0.401829E-06  0.257E-05    0.02     812.9  T
   5    -54.4329000  0.264180E-10  0.365E-05    0.02     570.8  T

   *** convergence criteria satisfied after 5 iterations ***

         #    Occupation            Energy/Eh            Energy/eV
      -------------------------------------------------------------
         1        2.0000           -0.8077093             -21.9789
       ...           ...                  ...                  ...
        44        2.0000           -0.4519193             -12.2974
        45        2.0000           -0.4416039             -12.0167
        46        2.0000           -0.4382805             -11.9262
        47        2.0000           -0.4364431             -11.8762
        48        1.9712           -0.4193192             -11.4103
        49        1.3939           -0.4159596             -11.3188
        50        0.9620           -0.4149744             -11.2920 (HOMO)
        51        0.6726           -0.4143188             -11.2742 (LUMO)
        52        0.0003           -0.4064085             -11.0589
        53        0.0000           -0.4013599             -10.9216
        54        0.0000           -0.3993727             -10.8675
        55                         -0.3978393             -10.8258
       ...                                ...                  ...
        92                          0.5733594              15.6019
      -------------------------------------------------------------
                  HL-Gap            0.0006557 Eh            0.0178 eV
             Fermi-level           -0.4150575 Eh          -11.2943 eV

 SCC (total)                   0 d,  0 h,  0 min,  0.075 sec
 SCC setup                      ...        0 min,  0.000 sec (  0.613%)
 Dispersion                     ...        0 min,  0.001 sec (  1.099%)
 classical contributions        ...        0 min,  0.000 sec (  0.094%)
 integral evaluation            ...        0 min,  0.014 sec ( 18.101%)
 iterations                     ...        0 min,  0.048 sec ( 64.779%)
 molecular gradient             ...        0 min,  0.009 sec ( 11.510%)
 printout                       ...        0 min,  0.003 sec (  3.768%)

         :::::::::::::::::::::::::::::::::::::::::::::::::::::
         ::                     SUMMARY                     ::
         :::::::::::::::::::::::::::::::::::::::::::::::::::::
         :: total energy             -53.817273406757 Eh    ::
         :: gradient norm              0.437211002759 Eh/a0 ::
         :: HOMO-LUMO gap              0.017841402980 eV    ::
         ::.................................................::
         :: SCC energy               -54.432899994162 Eh    ::
         :: -> isotropic ES           -0.008400535937 Eh    ::
         :: -> anisotropic ES          0.008550713598 Eh    ::
         :: -> anisotropic XC          0.042938496197 Eh    ::
         :: -> dispersion             -0.033240383834 Eh    ::
         :: repulsion energy           0.615339696451 Eh    ::
         :: add. restraining           0.000000000000 Eh    ::
         :::::::::::::::::::::::::::::::::::::::::::::::::::::

           -------------------------------------------------
          |                Property Printout                |
           -------------------------------------------------

    * Orbital Energies and Occupations

         #    Occupation            Energy/Eh            Energy/eV
      -------------------------------------------------------------
         1        2.0000           -0.8077093             -21.9789
       ...           ...                  ...                  ...
        38        2.0000           -0.4887331             -13.2991
        39        2.0000           -0.4859830             -13.2243
        40        2.0000           -0.4809836             -13.0882
        41        2.0000           -0.4761952             -12.9579
        42        2.0000           -0.4739852             -12.8978
        43        2.0000           -0.4618020             -12.5663
        44        2.0000           -0.4519193             -12.2974
        45        2.0000           -0.4416039             -12.0167
        46        2.0000           -0.4382805             -11.9262
        47        2.0000           -0.4364431             -11.8762
        48        1.9712           -0.4193192             -11.4103
        49        1.3939           -0.4159596             -11.3188
        50        0.9620           -0.4149744             -11.2920 (HOMO)
        51        0.6726           -0.4143188             -11.2742 (LUMO)
        52        0.0003           -0.4064085             -11.0589
        53        0.0000           -0.4013599             -10.9216
        54        0.0000           -0.3993727             -10.8675
        55                         -0.3978393             -10.8258
        56                         -0.3914812             -10.6527
        57                         -0.3673054              -9.9949
        58                         -0.3528530              -9.6016
        59                         -0.3265086              -8.8848
        60                         -0.3089247              -8.4063
        61                         -0.2935231              -7.9872
       ...                                ...                  ...
        92                          0.5733594              15.6019
      -------------------------------------------------------------
                  HL-Gap            0.0006557 Eh            0.0178 eV
             Fermi-level           -0.4150575 Eh          -11.2943 eV

     #   Z        covCN         q      C6AA      α(0)
     1   6 C      0.977    -0.104    39.190    10.512
     2   6 C      1.961     0.030    30.295     8.889
     3   6 C      1.962     0.038    30.109     8.861
     4   6 C      1.897    -0.072    33.089     9.290
     5   7 N      2.839     0.034    20.639     6.747
     6   6 C      3.111     0.151    24.593     8.124
     7   7 N      1.828    -0.181    25.739     7.518
     8   6 C      1.898     0.136    27.793     8.514
     9   6 C      1.962    -0.061    32.717     9.237
    10   7 N      1.833    -0.153    25.108     7.425
    11   6 C      3.177     0.075    25.926     8.314
    12   6 C      2.838     0.187    24.002     8.029
    13   7 N      0.923    -0.187    24.987     7.223
    14   7 N      1.904    -0.192    25.974     7.556
    15   6 C      3.236     0.157    23.820     7.918
    16   6 C      1.993     0.041    29.998     8.845
    17   6 C      2.984     0.080    26.200     8.396
    18   6 C      1.992    -0.087    33.432     9.338
    19   6 C      1.992    -0.006    31.203     9.021
    20   6 C      1.995    -0.007    31.226     9.024
    21   6 C      2.862     0.176    24.229     8.068
    22   8 O      1.702    -0.038    14.976     5.225
    23   6 C      0.855    -0.018    35.590     9.954

 Mol. C6AA /au·bohr⁶  :      14570.426237
 Mol. C8AA /au·bohr⁸  :     395614.902682
 Mol. α(0) /au        :        192.030328


Wiberg/Mayer (AO) data.
largest (>0.10) Wiberg bond orders for each atom
          total WBO             WBO to atom ...
     1  C   2.224        C    2 1.742    C    3 0.265    C    4 0.122
     2  C   3.774        C    3 1.826    C    1 1.742    C    4 0.155
     3  C   3.647        C    2 1.826    C    4 1.473    C    1 0.265
     4  C   2.974        C    3 1.473    N    5 1.001    C    2 0.155    C    1 0.122
     5  N   3.669        C    6 1.213    C   15 1.178    C    4 1.001
     6  C   3.862        N    7 1.301    N    5 1.213    C   11 1.106
     7  N   3.052        C    8 1.483    C    6 1.301
     8  C   3.717        N   10 1.639    N    7 1.483    N   13 0.420
     9  C   2.909        C   15 1.192    C   17 1.108    C   20 0.128    C   16 0.110
    10  N   3.109        C    8 1.639    C   12 1.124    N   13 0.208
    11  C   3.856        N   14 1.419    C    6 1.106    C   12 1.055
    12  C   3.943        N   13 1.668    N   10 1.124    C   11 1.055
    13  N   2.482        C   12 1.668    C    8 0.420    N   10 0.208
    14  N   3.067        C   11 1.419    C   15 1.313
    15  C   3.905        N   14 1.313    C    9 1.192    N    5 1.178
    16  C   3.746        C   19 1.676    C   17 1.297    C   20 0.339    C   18 0.135    C    9 0.110
    17  C   3.952        C   18 1.358    C   16 1.297    C    9 1.108
    18  C   3.607        C   21 1.363    C   17 1.358    C   19 0.420    C   20 0.136    C   16 0.135
    19  C   3.842        C   16 1.676    C   20 1.627    C   18 0.420
    20  C   3.717        C   19 1.627    C   21 1.295    C   16 0.339    C   18 0.136    C    9 0.128
    21  C   3.869        C   18 1.363    C   20 1.295    O   22 1.016
    22  O   2.621        C   23 1.535    C   21 1.016
    23  C   1.803        O   22 1.535
Topologies differ in total number of bonds
Writing corrected topology to xtbtopo.sdf

molecular dipole:
                 x           y           z       tot (Debye)
 q only:        1.231       0.461       0.259
   full:        1.222      -0.190       0.882       3.861
molecular quadrupole (traceless):
                xx          xy          yy          xz          yz          zz
 q only:      -18.992      50.577       6.724      84.932      38.401      12.269
  q+dip:      -39.411      47.020     -46.218      83.420       9.375      85.629
   full:      -42.080      46.850     -44.870      83.838       7.790      86.949


           -------------------------------------------------
          | TOTAL ENERGY              -53.817273406757 Eh   |
          | GRADIENT NORM               0.437211002759 Eh/α |
          | HOMO-LUMO GAP               0.017841402980 eV   |
           -------------------------------------------------

------------------------------------------------------------------------
 * finished run on 2020/06/11 at 15:52:08.456     
------------------------------------------------------------------------
 total:
 * wall-time:     0 d,  0 h,  0 min,  0.113 sec
 *  cpu-time:     0 d,  0 h,  0 min,  1.114 sec
 * ratio c/w:     9.884 speedup
 SCF:
 * wall-time:     0 d,  0 h,  0 min,  0.075 sec
 *  cpu-time:     0 d,  0 h,  0 min,  0.768 sec
 * ratio c/w:    10.234 speedup

normal termination of xtb
Note: The following floating-point exceptions are signalling: IEEE_UNDERFLOW_FLAG IEEE_DENORMAL

real    0m0.124s
user    0m0.955s
sys     0m0.187s

Python bindings:

from xtb.interface import Molecule
from xtb.interface import Calculator, Param
from rdkit import Chem
import numpy as np

def getSinglePointEnergy(ctab: str):
    m = Chem.MolFromMolBlock(ctab)
    n_conformers=m.GetNumConformers()
    if(n_conformers>0):
        atomic_numbers=np.array([atom.GetAtomicNum() for atom in m.GetAtoms()])
        conformer=m.GetConformers()[0]  #get the first conformer (we should only have a single one here)
        if(conformer.Is3D()):
            positions=conformer.GetPositions()
            #xtbmol = Molecule(atomic_numbers, positions)
            calc = Calculator(Param.GFN2xTB, atomic_numbers, positions,charge=0)
            res = calc.singlepoint()
            return(res.get_energy())
        else:
            raise Exception("You need to provide a 3D conformation of a molecule")
    else:
        raise Exception("You need to provide a 3D conformation of a molecule")

getSinglePointEnergy(mol)

mol="""
  Mrv1780 06112013133D          
libRbt.so/2013.1/901 2013/11/27
 23 25  0  0  0  0            999 V2000
    4.4805    8.0903   23.7408 C   0  0  0  0  0  0  0  0  0  0  0  0
    3.2758    7.9615   24.6858 C   0  0  0  0  0  0  0  0  0  0  0  0
    3.2357    8.5813   25.8817 C   0  0  0  0  0  0  0  0  0  0  0  0
    3.1873   10.1075   25.9102 C   0  0  0  0  0  0  0  0  0  0  0  0
    1.9462   10.5375   25.2461 N   0  0  0  0  0  0  0  0  0  0  0  0
    0.7523   10.5053   25.8000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.2909   10.1293   26.9964 N   0  0  0  0  0  0  0  0  0  0  0  0
   -1.0323   10.1983   27.2440 C   0  0  0  0  0  0  0  0  0  0  0  0
    3.0204   11.2327   23.1046 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.9366   10.7080   26.3758 N   0  0  0  0  0  0  0  0  0  0  0  0
   -0.1533   11.0667   24.8026 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.5522   11.1019   25.1404 C   0  0  0  0  0  0  0  0  0  0  0  0
   -2.4072   11.5667   24.2297 N   0  0  0  0  0  0  0  0  0  0  0  0
    0.5736   11.4000   23.7443 N   0  0  0  0  0  0  0  0  0  0  0  0
    1.8411   11.0338   24.0224 C   0  0  0  0  0  0  0  0  0  0  0  0
    5.3520   12.0306   23.6154 C   0  0  0  0  0  0  0  0  0  0  0  0
    3.9675   12.2618   23.6795 C   0  0  0  0  0  0  0  0  0  0  0  0
    3.4509   13.4279   24.2087 C   0  0  0  0  0  0  0  0  0  0  0  0
    6.2183   12.9874   24.1236 C   0  0  0  0  0  0  0  0  0  0  0  0
    5.7030   14.1479   24.6662 C   0  0  0  0  0  0  0  0  0  0  0  0
    4.3331   14.3732   24.6769 C   0  0  0  0  0  0  0  0  0  0  0  0
    3.8034   15.5097   25.2271 O   0  0  0  0  0  0  0  0  0  0  0  0
    4.5788   16.4496   25.9793 C   0  0  0  0  0  0  0  0  0  0  0  0
  1  2  1  0  0  0  0
  2  3  1  0  0  0  0
  3  4  1  0  0  0  0
  4  5  1  0  0  0  0
  5  6  1  0  0  0  0
  6  7  2  0  0  0  0
  7  8  1  0  0  0  0
  8 10  2  0  0  0  0
  6 11  1  0  0  0  0
 10 12  1  0  0  0  0
 11 12  2  0  0  0  0
 12 13  1  0  0  0  0
 11 14  1  0  0  0  0
  5 15  1  0  0  0  0
  9 15  1  0  0  0  0
 14 15  2  0  0  0  0
  9 17  1  0  0  0  0
 16 17  2  0  0  0  0
 17 18  1  0  0  0  0
 16 19  1  0  0  0  0
 19 20  2  0  0  0  0
 18 21  2  0  0  0  0
 20 21  1  0  0  0  0
 21 22  1  0  0  0  0
 22 23  1  0  0  0  0
M  END
"""

This python script yields the following output:

> getSinglePointEnergy(mol)
   1    -44.5513299 -0.445513E+02  0.153E+01    1.28       0.0  T
   2    -45.4179115 -0.866582E+00  0.962E+00    1.78       1.0  T
   3    -45.4024419  0.154696E-01  0.359E+00    1.11       1.0  T
   4    -45.3759017  0.265402E-01  0.196E+00    2.06       1.0  T
   5    -45.4782437 -0.102342E+00  0.971E-01    1.14       1.0  T
   6    -45.5091614 -0.309176E-01  0.289E-01    1.43       1.0  T
   7    -45.5097077 -0.546331E-03  0.154E-01    1.47       1.0  T
   8    -45.5098477 -0.139974E-03  0.469E-02    1.50       1.0  T
   9    -45.5098563 -0.859794E-05  0.143E-02    1.50       1.5  T
  10    -45.5098570 -0.753974E-06  0.503E-03    1.50       4.1  T
  11    -45.5098572 -0.167557E-06  0.166E-03    1.50      12.5  T
  12    -45.5098572 -0.552605E-08  0.530E-04    1.50      39.3  T
  13    -45.5098572 -0.124182E-08  0.175E-04    1.50     119.4  T
     SCC iter.                  ...        0 min,  0.252 sec
     gradient                   ...        0 min,  0.023 sec
-4.667743216484284

Tested on OSX and python bindings in docker container (please provide a mac version for the python bindings on conda-forge.

Expected behaviour

I'd expect the energies to be similar / identical

Additional context

Drop Travis CI

Travis CI integration seems broken and should be replaced by GitHub actions to get proper testing again.

M1 Mac Install error

Hi,

I have followed the conda install instructions for xtb

conda install xtb-python

However when I try to import from xtb I get this error:

from xtb.interface import Calculator from xtb.utils import get_method import numpy as np

`

---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
File ~/DD_tools/xtb-python/xtb/libxtb.py:32
     31 try:
---> 32     from ._libxtb import ffi, lib
     33 except ImportError:

ModuleNotFoundError: No module named 'xtb._libxtb'

During handling of the above exception, another exception occurred:

ImportError                               Traceback (most recent call last)
Cell In [2], line 1
----> 1 from xtb.interface import Calculator
      2 from xtb.utils import get_method
      3 import numpy as np

File ~/DD_tools/xtb-python/xtb/interface.py:25
     21 from enum import Enum, auto
     22 import numpy as np
---> 25 from .libxtb import (
     26     ffi as _ffi,
     27     lib as _lib,
     28     new_environment,
     29     new_molecule,
     30     new_calculator,
     31     new_results,
     32     copy_results,
     33     VERBOSITY_FULL,
     34     VERBOSITY_MINIMAL,
     35     VERBOSITY_MUTED
     36 )
     38 _verbosity_flags = {
     39     "full": VERBOSITY_FULL,
     40     "minimal": VERBOSITY_MINIMAL,
     41     "muted": VERBOSITY_MUTED
     42 }
     45 class XTBException(Exception):

File ~/DD_tools/xtb-python/xtb/libxtb.py:34
     32     from ._libxtb import ffi, lib
     33 except ImportError:
---> 34     raise ImportError("xtb C extension unimportable, cannot use C-API")
     37 VERBOSITY_FULL = 2
     38 VERBOSITY_MINIMAL = 1

ImportError: xtb C extension unimportable, cannot use C-API`

Do you know of any solution to this error? I have tried specific conda xtb version, but they all appear to lead to this error.

Thanks,
Mike

QCSchema Error handling

Describe the bug

When running GFNFF in the public QCArchive via QCEngine we have hit some errors but we unable to view the error message as creating the QCElemental atomic result seems to raise a validation error (see the message below). I think any time xtb fails and the return_result is set to 0 it needs to just be the correct length to be reshaped by the validator here and should depend on the driver requested. A full list of optimization IDS with the issue can be found here.

To Reproduce

Our xtb worker conda environment can be found here.

The error message from a gredient calculation is:

File "/home/chodera/miniconda/envs/qcfractal/lib/python3.7/site-packages/xtb/qcschema/harness.py", line 208, in run_qcschema
return qcel.models.AtomicResult(**ret_data, stdout=output)
File "pydantic/main.py", line 346, in pydantic.main.BaseModel.init
pydantic.error_wrappers.ValidationError: 1 validation error for AtomicResult
return_result
cannot reshape array of size 1 into shape (3) (type=value_error)

The inputs are recorded in the public QCArchive the dataset with the issues is a Torsiondrivedataset with the name OpenFF-benchmark-ligand-fragments-v1.0.

Expected behaviour

The error message should be recorded in the result.

Unhandled xTB errors such as NaN energy, incorrect net charge, and huge partial charges

Describe the bug

For some inputs, xtb-python produces impossible outputs which are not handled as errors.

To Reproduce

This is a script to demonstrate unhandled xTB errors for simple cubes.
The command line arguments are atomic number and grid spacing (in Angstroms) for a cube of the given element.
Metals tend to be more unstable.

import sys
import numpy as np
from scipy import constants
import xtb
from xtb.interface import Calculator, XTBException
from xtb.libxtb import VERBOSITY_MUTED
from xtb.utils import get_method
ANGSTROM_IN_BOHR = constants.physical_constants['Bohr radius'][0] * 1.0e10


def run_xtb(atomic_numbers, xyz, net_charge, n_unpaired_electrons, max_iter=250, conv=1.0, method="GFN2-xTB"):
    '''
    Run a single xtb job and return the result.
    Throws XTBException for errors or unrealistic results.

    Arguments:
        atomic_numbers (np.array): integer element labels for all atoms
        xyz (np.array): Nx3 array of coordinates for all atoms, in Angstroms
        n_unpaired_electrons (int): number of unpaired electrons in the system
        max_iter (int): max number of SCF iterations before giving up
        conv (float): SCF cutoffs, smaller means tighter convergence
    Returns:
        E_xtb: total system energy in Hartree
        gradient_xtb: dE/dxyz for each atom, in Hartree/Angstrom
        dipole_xtb: system dipole in electron-Angstrom (not available with PBC)
        qs_xtb: Mulliken atomic charges, in elementary charge units
    '''
    calc = Calculator(get_method(method), atomic_numbers, xyz / ANGSTROM_IN_BOHR,
                      charge=net_charge, uhf=n_unpaired_electrons)
    calc.set_verbosity(VERBOSITY_MUTED)
    calc.set_accuracy(conv)  # default = 1.0, smaller = tighter convergence
    calc.set_max_iterations(max_iter)  # default = 250
    result = calc.singlepoint()
    if result.check() != 0:
        raise XTBException(result.get_error())
    E_xtb = result.get_energy()
    if np.isnan(E_xtb):  # yet another convergence issue
        raise XTBException('Energy is NaN')
    qs_xtb = result.get_charges()
    if abs(net_charge - np.sum(qs_xtb)) > 1e-5:
        raise XTBException('Bad net charge: %d vs %f' % (net_charge, np.sum(qs_xtb)))
    if np.max(np.abs(qs_xtb)) > 4.0:
        raise XTBException('Very implausible partial charge: %f' % np.max(np.abs(qs_xtb)))
    dipole_xtb = result.get_dipole() * ANGSTROM_IN_BOHR  # from electron-Bohr to electron-Angstrom
    gradient_xtb = result.get_gradient() / ANGSTROM_IN_BOHR  # from Hartree/Bohr to Hartree/Angstrom
    # units: Hartree, Hartree/Angstrom, electron-Angstrom, electrons
    return E_xtb, gradient_xtb, dipole_xtb, qs_xtb

def test_metal_cubes(atomic_number, default_scale=3.0, cube_size=3):
    print('Cube of atomic number', atomic_number, 'with', cube_size**3, 'atoms, default interatomic r =', default_scale)
    for scale in np.arange(0.2, 1.2, 0.01):
        scale *= default_scale
        xyz = []
        for i in range(cube_size):
            for j in range(cube_size):
                for k in range(cube_size):
                    xyz.append((i, j, k))
        xyz = np.array(xyz, dtype=np.float64) * scale
        atomic_numbers = np.array([atomic_number] * len(xyz))
        q = np.sum(atomic_numbers) % 2  # if odd n electrons, remove 1
        try:
            E_xtb, gradient_xtb, dipole_xtb, qs_xtb = run_xtb(atomic_numbers, xyz, q, 0)
            # print('r = %.2f' % scale, 'E_xtb =', E_xtb)
        except XTBException as ex:
            print('r = %.2f' % scale, 'Failed,', ex)

print('xTB version', xtb.__version__)
atomic_number, default_scale = int(sys.argv[1]), float(sys.argv[2])
test_metal_cubes(atomic_number, default_scale)

Example input:
python xtb_huge_error.py 3 2.7
Output:

xTB version 20.1
Cube of atomic number 3 with 27 atoms, default interatomic r = 2.7
r = 0.92 Failed, Very implausible partial charge: 209.337257
r = 0.95 Failed, Very implausible partial charge: 96.060772
r = 0.97 Failed, Very implausible partial charge: 66.404307
r = 1.00 Failed, Very implausible partial charge: 163.766930
r = 1.05 Failed, Very implausible partial charge: 145.753860
r = 1.08 Failed, Bad net charge: 1 vs 1.000011
r = 1.13 Failed, Very implausible partial charge: 29.071110
r = 1.19 Failed, Very implausible partial charge: 257.358086
r = 1.22 Failed, Very implausible partial charge: 273.118857
r = 1.24 Failed, Bad net charge: 1 vs 0.412483
r = 1.27 Failed, Very implausible partial charge: 115.909595
r = 1.30 Failed, Very implausible partial charge: 19332.830109
r = 1.35 Failed, Very implausible partial charge: 5.019581
r = 1.38 Failed, Very implausible partial charge: 33.592007
r = 1.40 Failed, Very implausible partial charge: 33.003970
r = 1.43 Failed, Very implausible partial charge: 66.802335
r = 1.46 Failed, Bad net charge: 1 vs 1.000011
r = 1.49 Failed, Very implausible partial charge: 91.379054
r = 1.51 Failed, Bad net charge: 1 vs 1471240208384.000000
r = 1.76 Failed, Energy is NaN
r = 2.11 Failed, Energy is NaN

Expected behaviour

These error conditions should be handled within xtb or xtb-python, rather than requiring user checks. Probably the most alarming error here is Bad net charge: 1 vs 0.412483, where a significant fraction of an electron has appeared from nowhere.

Additional context

GFN1-xTB and GFN0-xTB don't have the same problems with bad net charges or implausible partial charges, but they can still give NaN for energy.

Distribution for Mac M1

Is your feature request related to a problem? Please describe.

I am finding that there is no distribution for M1 Mac machines on conda-forge

Describe the solution you'd like

Please provide a package compiled for M1 Mac machines as well on conda-forge.
I don't know how to do this?

Describe alternatives you've considered

I have considered directly installing, some dependencies are missing at the moment, I am trying to work that out. Tried with -Dla_backend=netlib, though it is missing the relevant OMP installation. Perhaps worth a separate issue.

Additional context

Initial attempt

(base) ➜  xtb-python git:(main) conda config --add channels conda-forge
Warning: 'conda-forge' already in 'channels' list, moving to the top
(base) ➜  xtb-python git:(main) conda create --name xtb-tmp xyb-python  
Collecting package metadata (current_repodata.json): done
Solving environment: failed with repodata from current_repodata.json, will retry with next repodata source.
Collecting package metadata (repodata.json): done
Solving environment: failed

PackagesNotFoundError: The following packages are not available from current channels:

  - xyb-python

Current channels:

  - https://conda.anaconda.org/conda-forge/osx-arm64
  - https://conda.anaconda.org/conda-forge/noarch
  - https://repo.anaconda.com/pkgs/main/osx-arm64
  - https://repo.anaconda.com/pkgs/main/noarch
  - https://repo.anaconda.com/pkgs/r/osx-arm64
  - https://repo.anaconda.com/pkgs/r/noarch

To search for alternate channels that may provide the conda package you're
looking for, navigate to

    https://anaconda.org

and use the search bar at the top of the page.

Searching for available packages:

(base) ➜  xtb-python git:(main) conda search xtb-python --channel conda-forge
Loading channels: done
No match found for: xtb-python. Search: *xtb-python*
# Name                       Version           Build  Channel             
scine-xtb-python               1.0.2    pyhd8ed1ab_0  conda-forge  

Computer is Mac mini (M1, 2020) with M1 chip.

Check typehints for ndarrays

Describe the bug

With numpy 1.20 we now have mypy typehints available for the linter, which therefore flags several instances of ndarrays which are missing typehints so far.

xtb/interface.py:290: error: Incompatible types in assignment (expression has type "None", variable has type "ndarray")
xtb/interface.py:297: error: Incompatible types in assignment (expression has type "None", variable has type "ndarray")
xtb/interface.py:346: error: Incompatible types in assignment (expression has type "None", variable has type "ndarray")
xtb/interface.py:670: error: Argument 2 to "__init__" of "Molecule" has incompatible type "List[int]"; expected "ndarray"
xtb/interface.py:670: error: Argument 3 to "__init__" of "Molecule" has incompatible type "List[float]"; expected "ndarray"
xtb/interface.py:670: error: Argument 6 to "__init__" of "Molecule" has incompatible type "Optional[List[float]]"; expected "Optional[ndarray]"
xtb/interface.py:670: error: Argument 7 to "__init__" of "Molecule" has incompatible type "Optional[List[bool]]"; expected "Optional[ndarray]"

To Reproduce

Run mypy on the xtb-python project using numpy 1.20

Expected behaviour

The flagged lines should be manually checked for correctness and compatible typehints should be added.

Getting infinite forces when using the GFN0-xTB calculator for periodic system

I am using the GFN0-xTB calculator for geometry optimization of a periodic system. However, the optimization always terminates at a certain step where some of the forces become infinite (or negative infinite). I am using xtb-python version 20.1, and running on Linux.

I attach below a zip file that contains two very similar structures, test1.traj and test2.traj. The energy is normal for test1.traj, but the forces become infinite. For test2.traj both energy and forces are normal.
structures.zip

Below is the code that should reproduce the behaviour:

from ase.io import read, write
from xtb.ase.calculator import XTB

# Read structure data
atoms = read('test1.traj') # test2.traj works fine

# Create the calculator for GFN0-xTB under periodic boundary conditions
calc = XTB(method='GFN0-xTB')
atoms.calc = calc

# Get the single point energy and forces
e = atoms.get_potential_energy()
f = atoms.get_forces()
print(e)
print(f)

Output:

-4523.6795731769935
[[-inf  inf -inf]
 [-inf  inf -inf]
 [-inf -inf -inf]
 [ inf -inf -inf]
 [ inf  inf -inf]
 [ inf  inf -inf]
 [-inf  inf -inf]
 [-inf  inf -inf]
 [-inf -inf -inf]
 [ inf -inf -inf]
 [ inf  inf -inf]
 [-inf  inf -inf]
 [ inf  inf  inf]
 [ inf  inf  inf]
 [ inf -inf  inf]
 [-inf -inf  inf]
 [-inf  inf  inf]
 [-inf -inf  inf]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [  0.   0.   0.]
 [-inf -inf -inf]]

Cannot deepcopy the Atoms object post calculation

Currently, it is not possible to deepcopy() the Atoms object after an xTB calculation with the ASE interface.

from copy import deepcopy
from xtb.ase.calculator import XTB
from ase.build import molecule
atoms = molecule("H2")
atoms.calc = XTB(method="GFN2-xTB")
atoms.get_potential_energy()
deepcopy(atoms)

Returns:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_3220/591948702.py in <module>
      5 atoms.calc = XTB(method="GFN2-xTB")
      6 atoms.get_potential_energy()
----> 7 deepcopy(atoms)

~/anaconda3/envs/xtb/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
    170                     y = x
    171                 else:
--> 172                     y = _reconstruct(x, memo, *rv)
    173 
    174     # If is its own copy, don't memoize.

~/anaconda3/envs/xtb/lib/python3.8/copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
    268     if state is not None:
    269         if deep:
--> 270             state = deepcopy(state, memo)
    271         if hasattr(y, '__setstate__'):
    272             y.__setstate__(state)

~/anaconda3/envs/xtb/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
    144     copier = _deepcopy_dispatch.get(cls)
    145     if copier is not None:
--> 146         y = copier(x, memo)
    147     else:
    148         if issubclass(cls, type):

~/anaconda3/envs/xtb/lib/python3.8/copy.py in _deepcopy_dict(x, memo, deepcopy)
    228     memo[id(x)] = y
    229     for key, value in x.items():
--> 230         y[deepcopy(key, memo)] = deepcopy(value, memo)
    231     return y
    232 d[dict] = _deepcopy_dict

~/anaconda3/envs/xtb/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
    170                     y = x
    171                 else:
--> 172                     y = _reconstruct(x, memo, *rv)
    173 
    174     # If is its own copy, don't memoize.

~/anaconda3/envs/xtb/lib/python3.8/copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
    268     if state is not None:
    269         if deep:
--> 270             state = deepcopy(state, memo)
    271         if hasattr(y, '__setstate__'):
    272             y.__setstate__(state)

~/anaconda3/envs/xtb/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
    144     copier = _deepcopy_dispatch.get(cls)
    145     if copier is not None:
--> 146         y = copier(x, memo)
    147     else:
    148         if issubclass(cls, type):

~/anaconda3/envs/xtb/lib/python3.8/copy.py in _deepcopy_dict(x, memo, deepcopy)
    228     memo[id(x)] = y
    229     for key, value in x.items():
--> 230         y[deepcopy(key, memo)] = deepcopy(value, memo)
    231     return y
    232 d[dict] = _deepcopy_dict

~/anaconda3/envs/xtb/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
    170                     y = x
    171                 else:
--> 172                     y = _reconstruct(x, memo, *rv)
    173 
    174     # If is its own copy, don't memoize.

~/anaconda3/envs/xtb/lib/python3.8/copy.py in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
    268     if state is not None:
    269         if deep:
--> 270             state = deepcopy(state, memo)
    271         if hasattr(y, '__setstate__'):
    272             y.__setstate__(state)

~/anaconda3/envs/xtb/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
    144     copier = _deepcopy_dispatch.get(cls)
    145     if copier is not None:
--> 146         y = copier(x, memo)
    147     else:
    148         if issubclass(cls, type):

~/anaconda3/envs/xtb/lib/python3.8/copy.py in _deepcopy_dict(x, memo, deepcopy)
    228     memo[id(x)] = y
    229     for key, value in x.items():
--> 230         y[deepcopy(key, memo)] = deepcopy(value, memo)
    231     return y
    232 d[dict] = _deepcopy_dict

~/anaconda3/envs/xtb/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
    159                     reductor = getattr(x, "__reduce_ex__", None)
    160                     if reductor is not None:
--> 161                         rv = reductor(4)
    162                     else:
    163                         reductor = getattr(x, "__reduce__", None)

TypeError: cannot pickle '_cffi_backend.__CDataGCP' object

Enforce C contiguous array order for NumPy array

While using xtb-python together with PySCF, I noticed a strange behaviour. Different energies would be obtained whether I got the coordinates from the PySCF Mole object or read them myself from an xyz file. I think the problem here is that PySCF uses F contiguous arrays, while xtb-python expects C contiguous. The problem is fixed by changing the order with np.ascontiguousarray. I guess that ideally this check + conversion should be done on the xib-python side.

mol = gto.Mole(verbose=0, basis="def2svp").fromfile("xtbopt.xyz", format="xyz")
elements = mol.atom_charges()
coordinates = mol.atom_coords()
coordinates.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False
calc_r = Calculator(get_method("GFNFF"), elements, coordinates)
results = calc_r.singlepoint()
results.get_energy()
5.134599834832412
coordinates = np.ascontiguousarray(mol.atom_coords())
coordinates.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False
calc_r = Calculator(get_method("GFNFF"), elements, coordinates)
results = calc_r.singlepoint()
results.get_energy()
-4.0651143277974615

xtbopt.xyz.zip

Single point calculator performs geometry optimization

Describe the bug

Hi,
I am using the example provided in the API documentation to compute the single point energy of a water molecule. It looks like the calculation is restarted (restarted? true in SETUP log when VERBOSITY_FULL):

          ...................................................
          :                      SETUP                      :
          :.................................................:
          :  # basis functions                   6          :
          :  # atomic orbitals                   6          :
          :  # shells                            4          :
          :  # electrons                         8          :
          :  max. iterations                   250          :
          :  Hamiltonian                  GFN2-xTB          :
          :  restarted?                       true          :
          :  GBSA solvation                  false          :
          :  PC potential                    false          :
          :  electronic temp.          300.0000000     K    :
          :  accuracy                    1.0000000          :
          :  -> integral cutoff          0.2500000E+02      :
          :  -> integral neglect         0.1000000E-07      :
          :  -> SCF convergence          0.1000000E-05 Eh   :
          :  -> wf. convergence          0.1000000E-03 e    :
          :  Broyden damping             0.4000000          :
          ...................................................

I have also compared the single point energy with xtb implementation results. The results are comparable only when --ohess flag is used (xtb --chrg 0 --pop --json --ohess --parallel 1 --grad ./H2O.xyz).

I think the python API is optimizing the structure under the hood.

To Reproduce

xTB_summary.tar.gz contains an example.py script that generates example.log with xTB python API. The xtbout_ohess.json and xtbout.json files are the results of using xtb with/without --ohess flags.

conda installed both packages:

  • xtb version is 6.4.1 (bd6e46d) and xtb-python is 20.2

Expected behaviour

xtb-python single point calculator should not perform geometry optimization if not requested.

Mac support

Is your feature request related to a problem? Please describe.

Would it be possible to add mac support on conda-forge? I know that xtb is available for mac already but I want to use it via the QCEngine interface to plug into other features like optimization with geomeTRIC and Torsiondrives and require xtb-python.

Accuracy of atoms.get_potential_energy

Describe the bug

The computed potential energy for a simple CH4 molecule computed through the ASE interface seems wrong when compared against Psi4 and NWChem.

To Reproduce

I am running Ubuntu 20.04.2 LTS with ase 3.22.0 and xtb-python version 20.1.
The python environment is provided by conda, using the following conda packages from the conda-forge channel: ase, psi4, xtb, xtb-python, nwchem.

I run the following xtb_test.py script:

import ase
import xtb
from ase.calculators.psi4 import Psi4
from ase.calculators.nwchem import NWChem
from xtb.ase.calculator import XTB

atoms = ase.Atoms(
    "CH4",
    [
        [-0.0034502 ,  0.01017081,  0.01938033],
        [-0.7954868 ,  0.5766599 , -0.5472012 ],
        [-0.39378393, -0.97992676,  0.2722862 ],
        [ 0.6344988 ,  0.4473651 ,  0.93568736],
        [ 0.59581804, -0.16517928, -0.8915708 ]
    ],
)

print("ase version: %s" % ase.__version__)
print("xtb version: %s" % xtb.__version__)

# From ANI-1 DFT reference data
energy_ref_Ha = -40.4805881714
print("reference: %.5f Ha" % energy_ref_Ha)

for name, calc in zip(
    ["psi4", "nwchem", "xtb"],
    [Psi4(), NWChem(), XTB(method="GFN2-xTB")]):

    atoms.calc = calc
    potential_energy_eV = atoms.get_potential_energy()
    # 27.211396641308 eV = 1 Ha
    potential_energy_Ha = potential_energy_eV / 27.211396641308

    print("'%s': %.5f Ha" % (name, potential_energy_Ha))

On my setup running this script produces the following output:

ase version: 3.22.0
xtb version: 20.1
reference: -40.48059 Ha
'psi4': -40.19151 Ha
'nwchem': -39.86620 Ha
'xtb': -4.15454 Ha

Expected behaviour

I expect that the potential energy computed for the XTB calculator approximately agrees with the energy computed by the other quantum chemistry codes, i.e. the Psi4 and NWChem calculators.

Additional context

The CH4 conformation is an out-of-equilibrium conformation from the ANI-1 DFT data set.

Unpaired electrons as input parameters in ase calculator

Hello,

In the standalone version of xtb you can define a file, .UHF, containing the number of unpaired electrons. Is it possible for the xtb-python to read that file? Would it be possible to include the number of unpaired electrons as additional input parameter for the ase calculator?

Will this be installed via conda?

I'm a bit confused by separating the Python API into a separate repo. If I install via conda, I would normally expect the Python API to be properly installed for that conda environment.

Will that be the case?

geometry optimisation with fixed dihedral

Is your feature request related to a problem? Please describe.

I'm interested in integrating the xTB into a package for the automatic procedure and it would be good if one could do a geometry optimisation with fixed dihedral using the xTB python interface.

This is an extension of #38

Describe the solution you'd like

The interface could mimic the openMM interface

Unit of the position

Is your feature request related to a problem? Please describe.

I wonder what is the unit of the coordinates? Assuming the interface as is shown https://xtb-python.readthedocs.io/en/latest/general-api.html#xtb.interface.Calculator

>>> from xtb.libxtb import VERBOSITY_MINIMAL
>>> from xtb.interface import Calculator, Param
>>> import numpy as np
>>> numbers = np.array([8, 1, 1])
>>> positions = np.array([
... [ 0.00000000000000, 0.00000000000000,-0.73578586109551],
... [ 1.44183152868459, 0.00000000000000, 0.36789293054775],
... [-1.44183152868459, 0.00000000000000, 0.36789293054775]])
...
>>> calc = Calculator(Param.GFN2xTB, numbers, positions)

With no explicit mention, one would imagine that the position is in the unit of angstrom.
However, it is mentioned here that https://xtb-python.readthedocs.io/en/latest/general-api.html#xtb.interface.Molecule.update

Update coordinates and lattice parameters, both provided in atomic units (Bohr)

So I guess the unit of the coordinates is actually in Bohr?

Expose verbosity setting via qcshema API

Is your feature request related to a problem? Please describe.

It would be very useful to be able to set the verbosity via a keyword in the qcshema interface. Running many xtb calculations in parallel for a prolonged period currently causes the output to leak to the terminal and eventually crash with an error caused by having too many open files.

Describe the solution you'd like

Change the qcschema interface to accept a verbosity keyword with options corresponding to the options here which then sets the verbosity of the calculation. If the verbosity is muted we can then avoid creating a temporary file as having too many of these causes the error.

Describe alternatives you've considered

Additional context

I can confirm that manually setting the verbosity to VERBOSITY_MUTED and removing the creation of the temporary file avoids the error.

EasyBuild module for xtb-python

Do you have any plans of creating an EasyBuild recipe for installing xtb-python?

I have used the xtb easyconfig file to install xtb and that works without issues. On top of that, I can install xtb-python by following the instructions here: https://xtb-python.readthedocs.io/en/latest/installation.html#building-from-source, but for creating an installation other users can benefit from it would be nicer to use EasyBuild.

My own few attempts have so far failed since installing xtb-python requires both a Meson Ninja step for building _libxtb and a step for setting the correct PYTHONPATH.

py-xtb and xtb report different solvation energies

I'm getting different solvation energies for water by using the xtb commandline interface and python interface.

Input:

3                                                                                
                                                                                 
O 0.000000 -0.000000 -0.066467                                                   
H 0.000000 0.758588 0.527436                                                     
H 0.000000 -0.798588 0.527436                                                    

commandline invocation:
xtb --alpb water --json --parallel 1 water.xyz

python script:

import numpy as np                                                               
from scipy import constants                                                      
from xtb.interface import Calculator, Param                                      
from xtb.libxtb import VERBOSITY_MINIMAL   , VERBOSITY_FULL                      
from xtb.utils import Solvent                                                    
                                                                                 
ANGSTROM_IN_BOHR = constants.physical_constants['Bohr radius'][0] * 1.0e10       

def run_xtb_python(atomic_numbers, positions, net_charge, solvent=None):         
    """                                                                          
    Run xTB with the provided python API                                         
    There is no error check                                                      
    """                                                                          
                                                                                 
    calc = Calculator(                                                           
        Param.GFN2xTB, atomic_numbers, positions / ANGSTROM_IN_BOHR, net_charge  
    )                                                                            
    calc.set_verbosity(VERBOSITY_FULL)                                           
    if solvent is not None:                                                      
        calc.set_solvent(solvent)                                                
                                                                                 
    res = calc.singlepoint()                                                     
                                                                                                                             
    energy = res.get_energy()                                                    
    # serialize and store a list object                                          
    gradient = (res.get_gradient() / ANGSTROM_IN_BOHR).tolist()                  
    charges = res.get_charges().tolist()                                         
                                                                                 
    print("eigenvalues", res.get_orbital_eigenvalues())                          
    print("total charge", sum(charges))                                          
    print("dipole", res.get_dipole())                                            
                                                                                 
    return {                                                                     
        "energy": energy,                                                        
        "charges": charges,                                                      
        "gradient": gradient                                                     
    }                                                                            

if __name__ == "__main__":
    PERIODIC_TABLE = {"H": 1, "O": 8}                                            
    atomic_numbers, positions = [], []                                           
    net_charge = 0                                                               
    with open("water.xyz") as fin:                                               
        token = next(fin)                                                        
        natoms = int(token)                                                      
        _ = next(fin)                                                            
        for i in range(natoms):                                                  
            elmnt, x, y, z = next(fin).split()                                   
            atomic_numbers.append(PERIODIC_TABLE[elmnt])                         
            positions.append([float(x), float(y), float(z)])                     
                                                                                 
    solvent = Solvent.h2o                         
                                                                                 
    output_data = run_xtb_python(                                                
        np.array(atomic_numbers),                                                
        np.array(positions),                                                     
        net_charge,                                                              
        solvent                                                                  
    )                                                                            

The xtb executable gives the following summary:

         :::::::::::::::::::::::::::::::::::::::::::::::::::::                                                                                                                                                                                
         ::                     SUMMARY                     ::                                                                                                                                                                                
         :::::::::::::::::::::::::::::::::::::::::::::::::::::                                                                                                                                                                                
         :: total energy              -5.086650340935 Eh    ::                                                                                                                                                                                
         :: total w/o Gsasa/hb        -5.072450640868 Eh    ::                                                                                                                                                                                
         :: gradient norm              0.034523773934 Eh/a0 ::                                                                                                                                                                                
         :: HOMO-LUMO gap             14.203449851402 eV    ::                                                                                                                                                                                
         ::.................................................::                                                                                                                                                                                
         :: SCC energy                -5.115460341784 Eh    ::                                                                                                                                                                                
         :: -> isotropic ES            0.055279536996 Eh    ::                                                                                                                                                                                
         :: -> anisotropic ES         -0.001553606638 Eh    ::                                                                                                                                                                                
         :: -> anisotropic XC          0.000001590124 Eh    ::                                                                                                                                                                                
         :: -> dispersion             -0.000124241951 Eh    ::                                                                                                                                                                                
         :: -> Gsolv                  -0.024975539514 Eh    ::                                                                                                                                                                                
         ::    -> Gborn               -0.010775839447 Eh    ::                                                                                                                                                                                
         ::    -> Gsasa                0.004887985565 Eh    ::                                                                                                                                                                                
         ::    -> Ghb                 -0.019499345345 Eh    ::                                                                                                                                                                                
         ::    -> Gshift               0.000411659713 Eh    ::                                                                                                                                                                                
         :: repulsion energy           0.028810000815 Eh    ::                                                                                                                                                                                
         :: add. restraining           0.000000000000 Eh    ::                                                                                                                                                                                
         :: total charge               0.000000000000 e     ::                                                                                                                                                                                
         :::::::::::::::::::::::::::::::::::::::::::::::::::::                                                                                                                                                                                

the python execution gives this summary

         :::::::::::::::::::::::::::::::::::::::::::::::::::::
         ::                     SUMMARY                     ::
         :::::::::::::::::::::::::::::::::::::::::::::::::::::
         :: total energy              -5.079191678312 Eh    ::
         :: total w/o Gsasa/hb        -5.071742364786 Eh    ::
         :: gradient norm              0.037702233171 Eh/a0 ::
         :: HOMO-LUMO gap             13.870116488842 eV    ::
         ::.................................................::
         :: SCC energy                -5.108001654563 Eh    ::
         :: -> isotropic ES            0.043341913075 Eh    ::
         :: -> anisotropic ES         -0.000309776201 Eh    ::
         :: -> anisotropic XC         -0.000217021538 Eh    ::
         :: -> dispersion             -0.000131539071 Eh    ::
         :: -> Gsolv                  -0.011920230479 Eh    ::
         ::    -> Gborn               -0.004470916953 Eh    ::
         ::    -> Gsasa                0.000215386523 Eh    ::
         ::    -> Ghb                 -0.009522143176 Eh    ::
         ::    -> Gshift               0.001857443127 Eh    ::
         :: repulsion energy           0.028809976217 Eh    ::
         :: add. restraining           0.000000000000 Eh    ::
         :: total charge              -0.000000000000 e     ::
         :::::::::::::::::::::::::::::::::::::::::::::::::::::

Apologies if I missed an import or other error in the python, I'm extracting this from a longer workflow.

libpython3.6m.a error when building _libxtb

I have compiled xtb sucessfully but got into troubles when creating xtb-python.

(py-3.6.10) [tang@grendel-s-s81n11:xtb-python-20200604]$ meson setup build --prefix=$PWD --libdir=xtb --default-library=shared
The Meson build system
Version: 0.53.0
Source dir: /home/tang/opt/xtb/xtb-python-20200604
Build dir: /home/tang/opt/xtb/xtb-python-20200604/build
Build type: native build
Project name: xtb-python
Project version: undefined
C compiler for the host machine: cc (gcc 4.8.5 "cc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)")
C linker for the host machine: cc GNU ld.bfd 2.23.52.0.1-55
Host machine cpu family: x86_64
Host machine cpu: x86_64
Found pkg-config: /usr/bin/pkg-config (0.27.1)
Run-time dependency xtb found: YES 6.3.0
Program python3 (cffi) found: YES (/home/tang/python-virtualenv/py-3.6.10/bin/python3) modules: cffi
Dependency python found: YES (pkgconfig)
Configuring _libxtb.h with command
Configuring _libxtb.c with command
Build targets in project: 2
 
Option default_library is: shared [default: static]
Found ninja-1.9.0.git.kitware.dyndep-1.jobserver-1 at /home/tang/python-virtualenv/py-3.6.10/bin/ninja
(py-3.6.10) [tang@grendel-s-s81n11:xtb-python-20200604]$ ninja -C build install
ninja: Entering directory `build'
[3/4] Linking target _libxtb.cpython-36m-x86_64-linux-gnu.so.
FAILED: _libxtb.cpython-36m-x86_64-linux-gnu.so
cc  -o _libxtb.cpython-36m-x86_64-linux-gnu.so  -Wl,--as-needed -Wl,--allow-shlib-undefined -shared -fPIC -Wl,--start-group -Wl,-soname,_libxtb.cpython-36m-x86_64-linux-gnu.so -Wl,--whole-archive lib_libxtb.a -Wl,--no-whole-archive /home/tang/opt/xtb/xtb-python-20200604/subprojects/xtb/install/lib64/libxtb.so /comm/swstack/core/python/3.6.10/lib/libpython3.6m.a -Wl,--end-group '-Wl,-rpath,$ORIGIN/../subprojects/xtb/install/lib64' -Wl,-rpath-link,/home/tang/opt/xtb/xtb-python-20200604/build/../subprojects/xtb/install/lib64
/usr/bin/ld: /comm/swstack/core/python/3.6.10/lib/libpython3.6m.a(abstract.o): relocation R_X86_64_32S against `_Py_NotImplementedStruct' can not be used when making a shared object; recompile with -fPIC
/comm/swstack/core/python/3.6.10/lib/libpython3.6m.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

It looks like I need to recompile python3 with -fPIC? Are there better ways to handle this?

Request: Optimization in xtb-python

Hello
I would like to request an optimization scheme in the python module like the xTB program itself. I know this is possible with ASE, but ASE tends to slow down things. Currently im getting a timing of 0.05 seconds for a simple linear water molecule with no angle using ASE and about 0.2 seconds for a carbon nanotube with 120 C atoms. I believe if an optimization is done without using ASE, it can run faster.
The reason for my request is that I am currently developing a VR platform for molecular simulation (scripting is done using python) and am implementing an interactive forcefield that needs a 5 step optimization to be run in approximately 0.015 seconds. If the optimization is slower, the relaxation will not be in "real-time".
I can imagine it is possible as the xTB program already has the ability to optimize using the different methods.

Thank you
Kind regards
Zan Mahmood

Cannot load libmkl_avx512.so or libmkl_def.so

Describe the bug

Hi,

I am getting

Intel MKL FATAL ERROR: Cannot load libmkl_avx512.so or libmkl_def.so

when I try to run a python script which imports xtb-python compiled with parent xtb-6.5.0

To Reproduce

Bash script to compile_and_install_xtb-python.sh:

#!/bin/bash

# Get standalone package

wget https://github.com/grimme-lab/xtb/releases/download/v$1/xtb-$1-linux-x86_64.tar.xz
tar xf xtb-$1-linux-x86_64.tar.xz
cd xtb-$1

# Edit first line on lib/pkgconfig/xtb.pc:

sed -i 's|prefix=\/|prefix='$PWD'|g' lib/pkgconfig/xtb.pc

# Define environment variables:

export PKG_CONFIG_PATH=$PWD/lib/pkgconfig

# Get and compile xtb-python:

git clone https://github.com/grimme-lab/xtb-python python
cd python

meson setup build --prefix=$PWD --default-library=shared

ninja -C build install

# Install to site-packages:

python3.8 -m pip install -e .

To install 6.5.0: ./compile_and_install_xtb-python.sh 6.5.0
(likewise for 6.4.1)

The test python script is the following (run.py):

from ase.io import read
from xtb.ase.calculator import XTB
atoms = read('H2CO.xyz')
atoms.calc = XTB(method="GFN2-xTB")
energy = atoms.get_potential_energy()
print(energy)

With xtb-6.4.1:

  1. ./compile_and_install_xtb-python.sh 6.4.1
  2. python3.8 run.py
  3. Output: -195.25932038970979

With xtb-6.5.0:

  1. ./compile_and_install_xtb-python.sh 6.5.0
  2. python3.8 run.py
  3. Output: Intel MKL FATAL ERROR: Cannot load libmkl_avx512.so or libmkl_def.so.

Expected behaviour

As shown before for xtb-6.4.1

I would appreciate any light on the subject.

Files

xtb-python-test.zip

Pointcharge gradient

Is it possible to get access to the pointcharge gradient in the API ? I could not find it.

Multiplicity in ASE Calculator

Hello,

I am using the xtb-python ase API with open-shell systems.
I would find it more intuitively to pass the multiplicity directly to the calculator object via an instance variable like multiplicity=N as implemented for other ASE Calculators.

Kind regards

Support cross-compilation

The current workflow for building the extension module does not support cross-compilation.

A patch to allow pointing to the right Python version is given below.

diff --git a/README.rst b/README.rst
index 955f183..f055aa8 100644
--- a/README.rst
+++ b/README.rst
@@ -80,7 +80,7 @@ configure the build of the extension with:
    ninja -C build install
 
 If you have several versions of Python installed you can point meson with
-the ``-Dpy=<version>`` option to the correct one.
+the ``-Dpy=$(command -v python3)`` option to the correct one.
 This will create the CFFI extension ``_libxtb`` and place it in the ``xtb``
 directory.
 
diff --git a/meson.build b/meson.build
index ca2fb66..a294869 100644
--- a/meson.build
+++ b/meson.build
@@ -55,7 +55,7 @@ endif
 
 pymod = import('python')
 python = pymod.find_installation(
-  'python@0@'.format(get_option('py')),
+  get_option('py'),
   modules: [
     'cffi',
   ],
diff --git a/meson_options.txt b/meson_options.txt
index 96647b6..51261e1 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -15,7 +15,7 @@
 # You should have received a copy of the GNU Lesser General Public License
 # along with xtb.  If not, see <https://www.gnu.org/licenses/>.
 
-option('py', type: 'string', value: '3',
+option('py', type: 'string', value: 'python3',
        description: 'Python version to link against.')
 option('la_backend', type: 'combo', value: 'mkl',
        choices: ['mkl', 'openblas', 'netlib'],

wanna get a function of optimization

Is your feature request related to a problem? Please describe.

In API documentation, there is only single point calculation method. It is really helpful if the python_xtb could contain the function of opimization class.

Describe the solution you'd like

Describe alternatives you've considered

Additional context

3 tests fail with ase and qcschema

Tests fail. I'm not sure the errors are non-negligible though?

xtb version 6.4.1 and xtb-python v20.2, I use intel compilers and mkl versions 2021.4.0 on CentOS 7.9

Running tests with:

pytest --pyargs xtb

Test output:

============================= test session starts ==============================
platform linux -- Python 3.9.6, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /home/energy/stly/modules
collected 30 items

test_interface.py ..........                                             [ 33%]
test_libxtb.py .                                                         [ 36%]
test_utils.py ..                                                         [ 43%]
ase/test_calculator.py .....                                             [ 60%]
ase/test_optimize.py F.F                                                 [ 70%]
qcschema/test_qcschema.py F........                                      [100%]

=================================== FAILURES ===================================
______________________________ test_gfn1xtb_bfgs _______________________________

    def test_gfn1xtb_bfgs():
        """Perform geometry optimization with GFN1-xTB and BFGS"""
    
        thr = 1.0e-5
    
        atoms = Atoms(
            symbols = "NHCHC2H3OC2H3ONHCH3",
            positions = np.array([
                [ 1.40704587284727, -1.26605342016611, -1.93713466561923],
                [ 1.85007200612454, -0.46824072777417, -1.50918242392545],
                [-0.03362432532150, -1.39269245193812, -1.74003582081606],
                [-0.56857009928108, -1.01764444489068, -2.61263467107342],
                [-0.44096297340282, -2.84337808903410, -1.48899734014499],
                [-0.47991761226058, -0.55230954385212, -0.55520222968656],
                [-1.51566045903090, -2.89187354810876, -1.32273881320610],
                [-0.18116520746778, -3.45187805987944, -2.34920431470368],
                [ 0.06989722340461, -3.23298998903001, -0.60872832703814],
                [-1.56668253918793,  0.00552120970194, -0.52884675001441],
                [ 1.99245341064342, -1.73097165236442, -3.08869239114486],
                [ 3.42884244212567, -1.30660069291348, -3.28712665743189],
                [ 3.87721962540768, -0.88843123009431, -2.38921453037869],
                [ 3.46548545761151, -0.56495308290988, -4.08311788302584],
                [ 4.00253374168514, -2.16970938132208, -3.61210068365649],
                [ 1.40187968630565, -2.43826111827818, -3.89034127398078],
                [ 0.40869198386066, -0.49101709352090,  0.47992424955574],
                [ 1.15591901335007, -1.16524842262351,  0.48740266650199],
                [ 0.00723492494701,  0.11692276177442,  1.73426297572793],
                [ 0.88822128447468,  0.28499001838229,  2.34645658013686],
                [-0.47231557768357,  1.06737634000561,  1.52286682546986],
                [-0.70199987915174, -0.50485938116399,  2.28058247845421],
            ]),
        )
    
        atoms.calc = XTB(method="GFN1-xTB", accuracy=2.0, cache_api=False)
        opt = BFGS(atoms)
        opt.run(fmax=0.1)
    
        assert approx(atoms.get_potential_energy(), thr) == -951.9006674709672
>       assert approx(np.linalg.norm(atoms.get_forces(), ord=2), thr) == 0.2052117803208497
E       AssertionError: assert 0.2051907763726757 ± 2.1e-06 == 0.2052117803208497
E        +  where 0.2051907763726757 ± 2.1e-06 = approx(0.2051907763726757, 1e-05)
E        +    where 0.2051907763726757 = <function norm at 0x7f95f1cf0790>(array([[ 0.02237361,  0.02429641, -0.06093066],\n       [-0.00613627,  0.020313  ,  0.03872088],\n       [-0.02944359, -...0481288, -0.03749684],\n       [ 0.00898936, -0.03774712, -0.02156718],\n       [ 0.05122454, -0.01808473, -0.06098617]]), ord=2)
E        +      where <function norm at 0x7f95f1cf0790> = <module 'numpy.linalg' from '/home/modules/software/SciPy-bundle/2021.10-intel-2021b/lib/python3.9/site-packages/numpy/linalg/__init__.py'>.norm
E        +        where <module 'numpy.linalg' from '/home/modules/software/SciPy-bundle/2021.10-intel-2021b/lib/python3.9/site-packages/numpy/linalg/__init__.py'> = np.linalg
E        +      and   array([[ 0.02237361,  0.02429641, -0.06093066],\n       [-0.00613627,  0.020313  ,  0.03872088],\n       [-0.02944359, -...0481288, -0.03749684],\n       [ 0.00898936, -0.03774712, -0.02156718],\n       [ 0.05122454, -0.01808473, -0.06098617]]) = <bound method Atoms.get_forces of Atoms(symbols='NHCHC2H3OC2H3ONHCH3', pbc=False, calculator=XTB(...))>()
E        +        where <bound method Atoms.get_forces of Atoms(symbols='NHCHC2H3OC2H3ONHCH3', pbc=False, calculator=XTB(...))> = Atoms(symbols='NHCHC2H3OC2H3ONHCH3', pbc=False, calculator=XTB(...)).get_forces

/home/modules/energy/software/xtb-python/20.2-intel-2021b-Python-3.9.6/xtb-python-20.2/xtb/ase/test_optimize.py:67: AssertionError
----------------------------- Captured stdout call -----------------------------
      Step     Time          Energy          fmax
BFGS:    0 11:23:59     -951.875911   9.91156e-01
BFGS:    1 11:23:59     -951.883077   1.11168e+00
BFGS:    2 11:23:59     -951.896465   1.46586e-01
BFGS:    3 11:23:59     -951.898042   1.16038e-01
BFGS:    4 11:23:59     -951.900667   9.72160e-02
_________________________ test_gfn2xtb_velocityverlet __________________________

    def test_gfn2xtb_velocityverlet():
        """Perform molecular dynamics with GFN2-xTB and Velocity Verlet Integrator"""
    
        thr = 1.0e-5
    
        atoms = Atoms(
            symbols = "NHCHC2H3OC2H3ONHCH3",
            positions = np.array([
                [ 1.40704587284727, -1.26605342016611, -1.93713466561923],
                [ 1.85007200612454, -0.46824072777417, -1.50918242392545],
                [-0.03362432532150, -1.39269245193812, -1.74003582081606],
                [-0.56857009928108, -1.01764444489068, -2.61263467107342],
                [-0.44096297340282, -2.84337808903410, -1.48899734014499],
                [-0.47991761226058, -0.55230954385212, -0.55520222968656],
                [-1.51566045903090, -2.89187354810876, -1.32273881320610],
                [-0.18116520746778, -3.45187805987944, -2.34920431470368],
                [ 0.06989722340461, -3.23298998903001, -0.60872832703814],
                [-1.56668253918793,  0.00552120970194, -0.52884675001441],
                [ 1.99245341064342, -1.73097165236442, -3.08869239114486],
                [ 3.42884244212567, -1.30660069291348, -3.28712665743189],
                [ 3.87721962540768, -0.88843123009431, -2.38921453037869],
                [ 3.46548545761151, -0.56495308290988, -4.08311788302584],
                [ 4.00253374168514, -2.16970938132208, -3.61210068365649],
                [ 1.40187968630565, -2.43826111827818, -3.89034127398078],
                [ 0.40869198386066, -0.49101709352090,  0.47992424955574],
                [ 1.15591901335007, -1.16524842262351,  0.48740266650199],
                [ 0.00723492494701,  0.11692276177442,  1.73426297572793],
                [ 0.88822128447468,  0.28499001838229,  2.34645658013686],
                [-0.47231557768357,  1.06737634000561,  1.52286682546986],
                [-0.70199987915174, -0.50485938116399,  2.28058247845421],
            ]),
        )
    
        atoms.calc = XTB(method="GFN2-xTB", cache_api=False)
    
        dyn = VelocityVerlet(atoms, timestep=1.0*fs)
        dyn.run(20)
    
        assert approx(atoms.get_potential_energy(), thr) == -896.9772346260584
>       assert approx(atoms.get_kinetic_energy(), thr) == 0.022411127028842362
E       AssertionError: assert 0.022409341448333585 ± 2.2e-07 == 0.022411127028842362
E        +  where 0.022409341448333585 ± 2.2e-07 = approx(0.022409341448333585, 1e-05)
E        +    where 0.022409341448333585 = <bound method Atoms.get_kinetic_energy of Atoms(symbols='NHCHC2H3OC2H3ONHCH3', pbc=False, momenta=..., calculator=XTB(...))>()
E        +      where <bound method Atoms.get_kinetic_energy of Atoms(symbols='NHCHC2H3OC2H3ONHCH3', pbc=False, momenta=..., calculator=XTB(...))> = Atoms(symbols='NHCHC2H3OC2H3ONHCH3', pbc=False, momenta=..., calculator=XTB(...)).get_kinetic_energy

/home/modules/energy/software/xtb-python/20.2-intel-2021b-Python-3.9.6/xtb-python-20.2/xtb/ase/test_optimize.py:150: AssertionError
_____________________________ test_gfn2xtb_energy ______________________________

    def test_gfn2xtb_energy():
        """Use QCSchema to calculate the energy of a halogen bond compound"""
        thr = 1.0e-7
    
        atomic_input = qcel.models.AtomicInput(
            molecule = {
                "symbols": [
                    "C", "C", "C", "C", "C", "C", "I", "H", "H",
                    "H", "H", "H", "S", "H", "C", "H", "H", "H",
                ],
                "geometry": [
                    -1.42754169820131, -1.50508961850828, -1.93430551124333,
                     1.19860572924150, -1.66299114873979, -2.03189643761298,
                     2.65876001301880,  0.37736955363609, -1.23426391650599,
                     1.50963368042358,  2.57230374419743, -0.34128058818180,
                    -1.12092277855371,  2.71045691257517, -0.25246348639234,
                    -2.60071517756218,  0.67879949508239, -1.04550707592673,
                    -2.86169588073340,  5.99660765711210,  1.08394899986031,
                     2.09930989272956, -3.36144811062374, -2.72237695164263,
                     2.64405246349916,  4.15317840474646,  0.27856972788526,
                     4.69864865613751,  0.26922271535391, -1.30274048619151,
                    -4.63786461351839,  0.79856258572808, -0.96906659938432,
                    -2.57447518692275, -3.08132039046931, -2.54875517521577,
                    -5.88211879210329, 11.88491819358157,  2.31866455902233,
                    -8.18022701418703, 10.95619984550779,  1.83940856333092,
                    -5.08172874482867, 12.66714386256482, -0.92419491629867,
                    -3.18311711399702, 13.44626574330220, -0.86977613647871,
                    -5.07177399637298, 10.99164969235585, -2.10739192258756,
                    -6.35955320518616, 14.08073002965080, -1.68204314084441,
                ],
            },
            driver = "energy",
            model = {
                "method": "GFN2-xTB",
            },
            keywords = {
                "accuracy": 1.0,
                "electronic_temperature": 300.0,
                "max_iterations": 50,
                "solvent": "none",
            }
        )
        dipole_moment = np.array(
            [0.3345064021648074, -1.0700925215553294, -1.2299195418603437]
        )
    
        atomic_result = run_qcschema(atomic_input)
    
        assert atomic_result.success
        assert approx(atomic_result.return_result, abs=thr) == -26.60185037124828
>       assert approx(atomic_result.properties.scf_dipole_moment, abs=thr) == dipole_moment
E       AssertionError: assert approx([0.3345115197707841 ± 1.0e-07, -1.070101790561011 ± 1.0e-07, -1.229921234359982 ± 1.0e-07]) == array([ 0.3345064021648074, -1.0700925215553294, -1.2299195418603437])
E        +  where approx([0.3345115197707841 ± 1.0e-07, -1.070101790561011 ± 1.0e-07, -1.229921234359982 ± 1.0e-07]) = approx(array([ 0.3345115197707841, -1.070101790561011 , -1.229921234359982 ]), abs=1e-07)
E        +    where array([ 0.3345115197707841, -1.070101790561011 , -1.229921234359982 ]) = AtomicResultProperties(return_energy=-26.60185043351621, scf_dipole_moment=array([ 0.3345115197707841, -1.070101790561011 , -1.229921234359982 ])).scf_dipole_moment
E        +      where AtomicResultProperties(return_energy=-26.60185043351621, scf_dipole_moment=array([ 0.3345115197707841, -1.070101790561011 , -1.229921234359982 ])) = AtomicResult(driver='energy', model={'method': 'GFN2-xTB', 'basis': None}, molecule_hash='3b522fc').properties

/home/modules/energy/software/xtb-python/20.2-intel-2021b-Python-3.9.6/xtb-python-20.2/xtb/qcschema/test_qcschema.py:73: AssertionError
=========================== short test summary info ============================
FAILED ase/test_optimize.py::test_gfn1xtb_bfgs - AssertionError: assert 0.205...
FAILED ase/test_optimize.py::test_gfn2xtb_velocityverlet - AssertionError: as...
FAILED qcschema/test_qcschema.py::test_gfn2xtb_energy - AssertionError: asser...
========================= 3 failed, 27 passed in 4.82s =========================

Build command:

meson --prefix /home/modules/energy/software/xtb-python/20.2-intel-2021b-Python-3.9.6 --default-library=shared -Dla_backend=mkl -Dfortran_link_args=-qopenmp  -Dlibdir=lib  /home/modules/energy/build/xtbpython/20.2/intel-2021b-Python-3.9.6/xtb-python-20.2/

No errors in build command with the following output.

#### Meson output:
 The Meson build system
 Version: 0.58.2
 Source dir: /home/modules/energy/build/xtbpython/20.2/intel-2021b-Python-3.9.6/xtb-python-20.2
 Build dir: /home/modules/energy/build/xtbpython/20.2/intel-2021b-Python-3.9.6/easybuild_obj
 Build type: native build
 Project name: xtb-python
 Project version: undefined
 C compiler for the host machine: icc (intel 2021.4.0 "icc (ICC) 2021.4.0 20210910")
 C linker for the host machine: icc ld.bfd 2.37
 Host machine cpu family: x86_64
 Host machine cpu: x86_64
 Found pkg-config: /usr/bin/pkg-config (0.27.1)
 Run-time dependency xtb found: YES 6.4.1
 Program python3 (cffi) found: YES (/home/modules/software/Python/3.9.6-GCCcore-11.2.0/bin/python3) modules: cffi
 Dependency python found: YES (pkgconfig)
 Configuring _libxtb.h with command
 Configuring _libxtb.c with command
 Build targets in project: 2
 
 Option libdir is: lib [default: xtb]
 Option default_library is: shared [default: static]
 Found ninja-1.10.2 at /home/modules/software/Ninja/1.10.2-GCCcore-11.2.0/bin/ninja

atomic spin populations

Is your feature request related to a problem? Please describe.

I would like to (quantitatively) analyze xTB atomic spin populations for radical chemistry

Describe the solution you'd like

In the same way that Result.get_charges() returns a numpy array of atomic charges, Result.get_spin_pops() would return two numpy arrays of alpha and beta atomic spin populations

Describe alternatives you've considered

The alternative is reading in the orbital coefficients and occupations, and performing the analysis externally. Seeing as the code for generating mulliken/CM5 charge populations exists internally, this will likely require just a slight modification to existing code.

Additional context

configure fails to find xtb because it only uses pkgconfig (with -Ddefault_library=shared)

When configured with -Ddefault_library=shared it fails to find xtb:

The Meson build system
Version: 0.63.2
Source dir: /disk-samsung/freebsd-ports/science/py-xtb/work/xtb-python-20.2-11-g3335421
Build dir: /disk-samsung/freebsd-ports/science/py-xtb/work/xtb-python-20.2-11-g3335421/_build
Build type: native build
Project name: xtb-python
Project version: undefined
C compiler for the host machine: cc (clang 14.0.5 "FreeBSD clang version 14.0.5 (https://github.com/llvm/llvm-project.git llvmorg-14.0.5-0-gc12386ae247c)")
C linker for the host machine: cc ld.lld 14.0.5
Host machine cpu family: x86_64
Host machine cpu: x86_64
Found pkg-config: /usr/local/bin/pkg-config (1.8.0)
Found CMake: /usr/local/bin/cmake (3.24.3)
Run-time dependency xtb found: NO (tried pkgconfig)
Looking for a fallback subproject for the dependency xtb

meson.build:33:2: ERROR: Subproject exists but has no meson.build file

This is because xtb doesn't install pkgconfig files, and meson doesn't try cmake for some reason.

Additionally, it shouldn't use subprojects when configured with -Ddefault_library=shared because then xtb is externally installed.

Fails to import xtb.interface on MacOS (M1)

I obtained xtb from homebrew and want to build xtb-python from source. Following the meson build instructions from the docs works, but when I want to import xtb.interface I get the following error:

from ._libxtb import ffi, lib
ModuleNotFoundError: No module named 'xtb._libxtb'

Here is the output from the meson build (meson setup build --prefix=$PWD --default-library=shared):

The Meson build system
Version: 0.63.3
Source dir: /Users/hannes/prog/xtb-python
Build dir: /Users/hannes/prog/xtb-python/build
Build type: native build
Project name: xtb-python
Project version: undefined
C compiler for the host machine: cc (clang 14.0.0 "Apple clang version 14.0.0 (clang-1400.0.29.202)")
C linker for the host machine: cc ld64 820.1
Host machine cpu family: aarch64
Host machine cpu: arm64
Found pkg-config: /opt/homebrew/bin/pkg-config (0.29.2)
Run-time dependency xtb found: YES 6.5.1
Program python3 (cffi) found: YES (/opt/homebrew/bin/python3) modules: cffi
Configuring _libxtb.h with command
Configuring _libxtb.c with command
Build targets in project: 2

xtb-python undefined

  User defined options
    default_library: shared
    prefix         : /Users/hannes/prog/xtb-python

Found ninja-1.11.1 at /opt/homebrew/bin/ninja

And here from ninja:

ninja: Entering directory `build'
[3/4] Linking target _libxtb.cpython-310-darwin.so
ld: warning: -undefined dynamic_lookup may not work with chained fixups
[3/4] Installing files.
Installing _libxtb.cpython-310-darwin.so to /Users/hannes/prog/xtb-python/opt/homebrew/lib/python3.10/site-packages/

Any help would be much appreciated!

Hessian/Frequency Support

I am looking to compute atomization enthalpies with through QCEngine and found it is not yet supported.

What's the route forward to adding support for Hessian calculations? I am not too familiar with XTB, but could help if given direction/advice.

xtb-python on PyPI

Hi @awvwgk, are there any plans to get xtb-python on PyPI? I'm working on a code that uses xtb-python and am just trying to sort out how I want to do my CI testing. It would be super convenient if I could pip install, but of course if that's not planned or feasible, I'll stick with conda!

[Feel free to close at your leisure]

Cheers!
Andrew

Strange segmentation fault

Describe the bug

Failed to run an optimization for a periodic cell by employing method GFN0-xTB with more than 2 adsorbed molecules within the MOF pore. The same run happens to show no error, and converge smoothly when using xTB without the xtb-python API.

To Reproduce

from ase.optimize.bfgslinesearch import BFGSLineSearch
from ase.build import molecule
from ase.atoms import Atoms
from numpy import loadtxt
from xtb.ase.calculator import XTB
from ase.constraints import FixAtoms
from ase.data.pubchem import pubchem_atoms_search
from ase.io import write

def runmole(adsorbate, name, calc):
    adsorbate.calc = calc
    adsorbateopt = BFGSLineSearch(adsorbate, trajectory = '%sads.trj' % name, logfile = '%sads.log' % name)
    adsorbateopt.run(fmax=0.0005)
    write('%s.xyz' % name, adsorbate)
    return adsorbate.get_potential_energy()

def runopt(name, natom, Eadsorbate, Emof, lattice, calc):
    e = 0
    for i in range(4):
        S = loadtxt('%s.ads.%d.xyz' % (name, i), usecols = [0], dtype = str)
        P = loadtxt('%s.ads.%d.xyz' % (name, i), usecols = [1, 2, 3], dtype = float)
        ads = Atoms(symbols = S, positions = P, cell = lattice, pbc = [True, True, True])
        fixed = list(range(len(ads) - (i+1)*natom))
        ads.constraints = [FixAtoms(indices=fixed)]
        ads.calc = calc
        opt = BFGSLineSearch(ads, trajectory = '%sads%d.trj' % (name, i), logfile = '%sads%d.log' % (name, i))
        opt.run(fmax=0.0005)
        write('%sads%d.cif' % (name, i), ads)
        eads = ads.get_potential_energy() - (i+1)*Eadsorbate - Emof
        e = eads - e
        print('%sads%d = %10.8f %10.8f' % (name, i, eads, e))

lattice = loadtxt('CELL_PARAMETERS_MOF_4x3x1', usecols = [0, 1, 2], dtype = float)
calc = XTB(method='GFN0-xTB', accuracy = 1.0)
Emof = -10207.074487838794
Edmf = runmole(pubchem_atoms_search(name = 'dmf'), 'dmf', calc)
runopt('dmf', 12, Edmf, Emof, lattice, calc)
  1. What is your setup, which version are you running (current master is subject to change)
    xtb-6.3.2
    xtb-python (API_VERSION: 1.0.0)
    ase 3.19.1.

  2. output showing the error
    Segmentation fault (core dumped)

All input and output file to verify this report.-->
test.gz

Expected behaviour

Printing a table of adsorption energy.

ASE optimization error: "Type Error: Object of type Param is not JSON serializable"

Hi I am new to xtb. I found the new release 6.3.0 very interesting and exciting since GFN1 is now available for PBC systems. It works fine when I do single point calculations, but when I use the ASE BFGS optimizer, I got the following error:

  File "/home/modules/software/Python/3.7.4-GCCcore-8.3.0/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/home/modules/software/Python/3.7.4-GCCcore-8.3.0/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/home/energy/shuha/newASE/ase/io/jsonio.py", line 37, in default
    return json.JSONEncoder.default(self, obj)
  File "/home/modules/software/Python/3.7.4-GCCcore-8.3.0/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} ' 
TypeError: Object of type Param is not JSON serializable

This is my python script:

from ase.io import *
from ase.optimize.bfgs import BFGS
from xtb.ase.calculator import XTB
from xtb.utils import get_method
calc = XTB(method=get_method('GFN1-xTB'))
atoms = read('test.traj')
atoms.set_calculator(calc)
opt = BFGS(atoms, trajectory = 'relaxation_gfn1.traj', logfile='relaxation.log')
opt.run(fmax=0.1)
atoms.get_potential_energy()
atoms.get_forces()

Installing with Conda isn't working

I'm trying to create a docker machine expecially for developing app for xtb.
But when I try to from xtb.libxtb import VERBOSITY_FULL I have error ImportError: xtb C extension unimportable, cannot use C-API

I tried to use python 3.8 (because it seems the code it is 3.8), conda. So I followed the conda install recomandation.

My actual config is:

Dockerfile

FROM buildpack-deps:bullseye

[...]

RUN conda install -y -c anaconda python=3.8 \
    && conda config --add channels conda-forge \
    && conda install -y -c conda-forge xtb-python qcelemental ase

[...]

Full error:

Python 3.8.15 (default, Nov 24 2022, 15:19:38) 
[GCC 11.2.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from xtb.libxtb import VERBOSITY_FULL
Traceback (most recent call last):
  File "/opt/conda/lib/python3.8/site-packages/xtb/libxtb.py", line 32, in <module>
    from ._libxtb import ffi, lib
ImportError: /opt/conda/lib/python3.8/site-packages/_cffi_backend.cpython-38-x86_64-linux-gnu.so: undefined symbol: ffi_type_uint32, version LIBFFI_BASE_7.0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/conda/lib/python3.8/site-packages/xtb/libxtb.py", line 34, in <module>
    raise ImportError("xtb C extension unimportable, cannot use C-API")
ImportError: xtb C extension unimportable, cannot use C-API
>>>

parallelisation in the xtb python interface

Is your feature request related to a problem? Please describe.

I'm interested in using xtb python interface to run xTB calculation via QCEngine and I wish there is a way of running xTB in parallel.

Describe the solution you'd like

>>> from xtb.qcschema.harness import run_qcschema
>>> import qcelemental as qcel
>>> atomic_input = qcel.models.AtomicInput(
...     molecule = qcel.models.Molecule(
...         symbols = ["O", "H", "H"],
...         geometry = [
...             0.00000000000000,  0.00000000000000, -0.73578586109551,
...             1.44183152868459,  0.00000000000000,  0.36789293054775,
...            -1.44183152868459,  0.00000000000000,  0.36789293054775
...         ],
...     ),
...     driver = "energy",
...     model = {
...         "method": "GFN2-xTB",
...     },
...     keywords = {
...         "threads": 16,
...         "accuracy": 1.0,
...         "max_iterations": 50,
...     },
... )

Memory Overflow of the ASE calculator

Describe the bug

I try to calculate the xtb energies of the QM9 database - 133885 structures. But at 6000 structures the memory usage exceeds 32GB, resulting in my calculation to crash. This can be solved by copying the ASE atoms object before every evaluation.

To Reproduce

Example workflow, which fails:

from ase.io import read
import matplotlib.pyplot as plt
import os
from tqdm import tqdm
from xtb.ase.calculator import XTB


def calc_energy(structure):
    structure.calc = XTB(method="GFN2-xTB")
    eng_pot = structure.get_potential_energy()
    return eng_pot


if __name__ == "__main__":
    path = "/home/janssen/pyiron/projects/2023-02-19-xtb-high-throughput/dsgdb9nsd"
    structure_lst = [read(os.path.join(path, f), format="xyz") for f in os.listdir(path)]
    potential_energy_lst = [calc_energy(structure=structure) for structure in tqdm(structure_lst)]
    print("Done")

Expected behaviour

This is the working example:

from ase.io import read
import matplotlib.pyplot as plt
import os
from tqdm import tqdm
from xtb.ase.calculator import XTB


def calc_energy(structure):
    structure.calc = XTB(method="GFN2-xTB")
    eng_pot = structure.get_potential_energy()
    return eng_pot


if __name__ == "__main__":
    path = "/home/janssen/pyiron/projects/2023-02-19-xtb-high-throughput/dsgdb9nsd"
    structure_lst = [read(os.path.join(path, f), format="xyz") for f in os.listdir(path)]
    potential_energy_lst = [calc_energy(structure=structure.copy()) for structure in tqdm(structure_lst)]
    print("Done")

In particular I changed the line:

< potential_energy_lst = [calc_energy(structure=structure) for structure in tqdm(structure_lst)]
> potential_energy_lst = [calc_energy(structure=structure.copy()) for structure in tqdm(structure_lst)]

Additional context

I tried both cache_api=True and cache_api=False still this does not fix the issue. A similar option would be great to achieve the same reset I get from copying the atoms object.

New Release

Is your feature request related to a problem? Please describe.

Would it be possible to have a new release of xtb-python and upload it to conda-forge with some of the new features? This fix #74 would be very helpful in particular.

Can't redirect stdout from calculator singlepoint()

I have an application that will be running a lot of xtb calculations. I don't want my main output to be clogged with a lot of output from xtb itself but instead would like to write this information to a different file using redirection.

Normally this is possible with contextlib in python but contextlib can't capture the stdout from Calculator.

For example, the following code still prints out the SCC iteration information to the standard output (which I don't want). It should be written to log.txt instead.

import contextlib
import numpy as np
from xtb.interface import Calculator
from xtb.utils import get_method
from xtb.interface import Environment

numbers = np.array([8, 1, 1]) 
positions = np.array([
[ 0.00000000000000, 0.00000000000000,-0.73578586109551],
[ 1.44183152868459, 0.00000000000000, 0.36789293054775],
[-1.44183152868459, 0.00000000000000, 0.36789293054775]])

calc = Calculator(get_method("GFN2-xTB"), numbers, positions)

with open('log.txt','a') as f:
    with contextlib.redirect_stdout(f):
        res = calc.singlepoint()  # energy printed is only the electronic part
E = res.get_energy()
print(E)
g = res.get_gradient()
print(g)

c = res.get_charges()
print(c) 

CM5 charges from XTB ASE interface

Is your feature request related to a problem? Please describe.

Is there a way to get CM5 charges instead of Mulliken charges from xtb-ase interface? Any help would be highly appreciated.

Describe the solution you'd like

I have used the command line executable to generate CM5 charges, but it would be great to include that in python API.

Additional context

I have published on CM5 charges and their utility for modeling organic drug-like molecules. See the link below.
https://pubs.acs.org/doi/10.1021/acs.jctc.5b00414
Adding this feature would help seamlessly integrate XTB with force fields such as OpenFF

Looking for (co-)maintainers

I'm looking for somebody interested in developing and maintaining this project going forward.

Personally, I consider this project finished given the initial scope was to provide native integration with QCEngine and ASE for the xTB methods, therefore I'm not planning to add new features, which doesn't mean this project is not going to accept any feature additions.

Current scope

The project mainly deals with Python/C interop for the C-API exposed in xtb (see src/api in the xtb repository) and development is therefore tied tightly to the xtb C bindings. There might be an argument to drop this project in favor of the tblite library in the future or use tblite directly to provide the functionality exposed here. The overall design principle of the C and Python bindings are described in this presentation for the ESL Fortran OOP seminar series.

Project assets

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.