Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modernise packaging, and better manage optional depencencies #56

Merged
merged 10 commits into from
Jun 13, 2024
66 changes: 66 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
[build-system]
requires = [
"setuptools",
]
build-backend = "setuptools.build_meta"

[project]
name = "qstack"
#version = "0.0.0"
dynamic = ["version"]
description = "Stack of codes for dedicated pre- and post-processing tasks for Quantum Machine Learning"
readme = "README.md"
license = {file = "LICENSE"}

authors = [
{name = "Alberto Fabrisio"}, # orcid = "0000-0002-4440-3149"
liam-o-marsh marked this conversation as resolved.
Show resolved Hide resolved
{name = "Ksenia Briling", email = "[email protected]"}, # orcid = "0000-0003-2250-9898"
{name = "Yannick Calvino", email = "[email protected]"}, # orcid = "0009-0008-9573-7772"
{name = "Liam Marsh", email = "[email protected]"}, # orcid = "0000-0002-7276-5673"
]
maintainers = [
{name = "Ksenia Briling", email = "[email protected]"}, # orcid = "0000-0003-2250-9898"
{name = "Yannick Calvino", email = "[email protected]"}, # orcid = "0009-0008-9573-7772"
{name = "Liam Marsh", email = "[email protected]"}, # orcid = "0000-0002-7276-5673"
]

classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: C",
"License :: OSI Approved :: MIT License",
"Development Status :: 3 - Alpha",
"Intended Audience :: Science/Research",
"Programming Language :: Python :: Implementation :: CPython",
]

requires-python = ">=3.9"
dependencies = [
'numpy',
'scipy',
'pyscf',
'tqdm',
#'scikit-learn',
#'equistore-core @ git+https://github.com/lab-cosmo/equistore.git@e5b9dc365369ba2584ea01e9d6a4d648008aaab8#subdirectory=python/equistore-core',
]

[project.optional-dependencies]
qml = ["ase"]
regression = ["scikit-learn"]
wigner = ["sympy"]
gmol = ["cell2mol"]
equio = ["equistore-core @ git+https://github.com/lab-cosmo/equistore.git@e5b9dc365369ba2584ea01e9d6a4d648008aaab8#subdirectory=python/equistore-core"]
all = ["qstack[qml,regression,wigner,equio,gmol]"]

#dev = ["tqdm"] # those are deps for the tests

[project.urls]
Repository = "https://github.com/lcmd-epfl/Q-stack.git"
"Bug Tracker" = "https://github.com/lcmd-epfl/Q-stack/issues"


[tool.setuptools.packages.find]
where = ["."]
exclude = ["tests","examples"]
namespaces = false
[tool.setuptools.package-data]
"*" = ['regression/lib/manh.c', 'spahm/rho/basis_opt/*.bas']
9 changes: 8 additions & 1 deletion qstack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
from qstack import fields
from qstack import basis_opt
from qstack import spahm
from qstack import regression
from qstack import mathutils
from qstack import orcaio

try:
import sklearn
except ImportError:
pass
else:
from qstack import regression
del sklearn
14 changes: 12 additions & 2 deletions qstack/compound.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,18 @@ def gmol_to_mol(fin, basis="def2-svp"):
pyscf Mole: pyscf Mole object.
"""

from cell2mol.tmcharge_common import Cell, atom, molecule, ligand, metal
from cell2mol.tmcharge_common import labels2formula
try:
from cell2mol.tmcharge_common import Cell, atom, molecule, ligand, metal
from cell2mol.tmcharge_common import labels2formula
except ImportError:
print("""

ERROR: cannot import ĉell2mol. Have you installed qstack with the \gmol\" option?\n\n
liam-o-marsh marked this conversation as resolved.
Show resolved Hide resolved
(for instance, with `pip install qstack[gmol] or `pip install qstack[all]``)

""")
raise


# Open and read the file
if fin.endswith(".gmol"):
Expand Down
6 changes: 3 additions & 3 deletions qstack/fields/decomposition.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import numpy as np
import scipy
from pyscf import scf
import qstack
from qstack import compound

def decompose(mol, dm, auxbasis):
"""Fit molecular density onto an atom-centered basis.
Expand All @@ -15,8 +15,8 @@ def decompose(mol, dm, auxbasis):
A copy of the pyscf Mole object with the auxbasis basis in a pyscf Mole object, and a 1D numpy array containing the decomposition coefficients.
"""

auxmol = qstack.compound.make_auxmol(mol, auxbasis)
S, eri2c, eri3c = qstack.fields.decomposition.get_integrals(mol, auxmol)
auxmol = compound.make_auxmol(mol, auxbasis)
S, eri2c, eri3c = get_integrals(mol, auxmol)
c = get_coeff(dm, eri2c, eri3c)
return auxmol, c

Expand Down
13 changes: 7 additions & 6 deletions qstack/fields/excited.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import numpy as np
import pyscf
from pyscf import scf, tdscf
from qstack import compound, fields
from qstack import compound
from qstack.fields import moments

def get_cis(mf, nstates):
"""
Expand All @@ -26,7 +27,7 @@ def get_cis_tdm(td):

def get_holepart(mol, x, coeff):
"""Computes the hole and particle density matrices (atomic orbital basis) of selected states.

Args:
mol (pyscf Mole): pyscf Mole object.
x (numpy ndarray): Response vector (nstates×occ×virt) normalized to 1.
Expand Down Expand Up @@ -71,11 +72,11 @@ def exciton_properties_c(mol, hole, part):
part (numpy ndarray): Particle density matrix.

Returns:
Three floats: the hole-particle distance, the hole size, and the particle size respectively.
Three floats: the hole-particle distance, the hole size, and the particle size respectively.
"""

hole_N, hole_r, hole_r2 = fields.moments.r2_c(hole, mol)
part_N, part_r, part_r2 = fields.moments.r2_c(part, mol)
hole_N, hole_r, hole_r2 = moments.r2_c(hole, mol)
part_N, part_r, part_r2 = moments.r2_c(part, mol)

dist = np.linalg.norm(hole_r-part_r)
hole_extent = np.sqrt(hole_r2-hole_r@hole_r)
Expand All @@ -91,7 +92,7 @@ def exciton_properties_dm(mol, hole, part):
part (numpy ndarray): Particle density matrix.

Returns:
Three floats: the hole-particle distance, the hole size, and the particle size respectively.
Three floats: the hole-particle distance, the hole size, and the particle size respectively.
"""

with mol.with_common_orig((0,0,0)):
Expand Down
2 changes: 1 addition & 1 deletion qstack/fields/moments.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np
import pyscf
from qstack import compound, fields
from qstack import compound

def first(mol, rho):
""" Computes the transition dipole moments.
Expand Down
2 changes: 1 addition & 1 deletion qstack/mathutils/wigner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import sys
import sympy as sp
from sympy import symbols, Symbol, simplify, expand, cancel, expand_trig, Ynm, Ynm_c, Matrix, poly, zeros
from .xyz_integrals_sym import xyz as xyzint
from sympy import symbols, Symbol, simplify, expand, cancel, expand_trig, Ynm, Ynm_c, Matrix, poly, zeros


# variables
Expand Down
12 changes: 11 additions & 1 deletion qstack/mathutils/xyz_integrals_sym.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
#!/usr/bin/env python3

import sys
import sympy

try:
import sympy
except ImportError:
print("""

ERROR: cannot import sympy. Have you installed qstack with the \"wigner\" option?\n\n
(for instance, with `pip install qstack[wigner]` or `pip install qstack[all]`)

""")
raise

def xyz(n,m,k):
# computes the integral of x^2k y^2n z^2m over a sphere
Expand Down
16 changes: 15 additions & 1 deletion qstack/qml/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
from qstack.qml import slatm
try:
import ase
except ImportError:
print("""

ERROR: cannot import ase. Have you installed qstack with the \"qml\" option?\n\n
(for instance, with `pip install qstack[qml]` or `pip install qstack[all]`)

""")
raise
else:
from . import b2r2
from . import slatm
del ase

8 changes: 3 additions & 5 deletions qstack/regression/kernel_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy
from types import SimpleNamespace
import qstack
from qstack.regression import __path__ as REGMODULE_PATH
import argparse


Expand Down Expand Up @@ -120,7 +120,6 @@ def get_covariance(mol1, mol2, max_sizes, kernel , sigma=None):
.. todo::
Write the docstring
"""
from qstack.regression.kernel_utils import get_kernel
species = sorted(max_sizes.keys())
mol1_dict = mol_to_dict(mol1, species)
mol2_dict = mol_to_dict(mol2, species)
Expand Down Expand Up @@ -213,7 +212,6 @@ def cdist(X, Y):
numpy.exp(K, K)
return K


def my_kernel_c(akernel):
"""

Expand All @@ -225,9 +223,9 @@ def my_kernel_c(akernel):
array_2d_double = numpy.ctypeslib.ndpointer(dtype=numpy.float64, ndim=2, flags='CONTIGUOUS')
def kernel_func_c(X, Y, gamma):
try:
manh = ctypes.cdll.LoadLibrary(qstack.regression.__path__[0]+"/lib/manh.so")
manh = ctypes.cdll.LoadLibrary(REGMODULE_PATH[0]+"/lib/manh.so")
except:
manh = ctypes.cdll.LoadLibrary(qstack.regression.__path__[0]+"/lib/manh"+sysconfig.get_config_var('EXT_SUFFIX'))
manh = ctypes.cdll.LoadLibrary(REGMODULE_PATH[0]+"/lib/manh"+sysconfig.get_config_var('EXT_SUFFIX'))
if akernel == 'myLfast':
kfunc = manh.manh
elif akernel == 'myG':
Expand Down
13 changes: 12 additions & 1 deletion qstack/regression/regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@

import numpy as np
import scipy
from sklearn.model_selection import train_test_split

try:
from sklearn.model_selection import train_test_split
except ImportError:
print("""

ERROR: cannot import scikit-learn. Have you installed qstack with the \"regression\" option?\n\n
(for instance, with `pip install qstack[regression] or `pip install qstack[all]``)

""")
raise

liam-o-marsh marked this conversation as resolved.
Show resolved Hide resolved
from qstack.regression.kernel_utils import get_kernel, defaults, ParseKwargs
from qstack.tools import correct_num_threads
from qstack.mathutils.fps import do_fps
Expand Down
2 changes: 1 addition & 1 deletion qstack/spahm/rho/rep_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from os.path import join, isfile, isdir
import numpy as np
import pyscf
from qstack import compound, spahm
from qstack import compound
import qstack.tools as tls
from . import utils, dmb_rep_atom as dmba, dmb_rep_bond as dmbb

Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ iniconfig==1.1.1
packaging==21.3
pluggy==1.0.0
py==1.11.0
#cython==0.29.24
pyparsing==3.0.6
pyscf==2.0.1
pytest==6.2.5
numpy===1.22.3
scipy==1.10
toml==0.10.2
scikit-learn==0.24.2
#scikit-learn==1.0.2
ase==3.22
tqdm==4.66
equistore-core @ git+https://github.com/lab-cosmo/equistore.git@e5b9dc365369ba2584ea01e9d6a4d648008aaab8#subdirectory=python/equistore-core
Expand Down
15 changes: 0 additions & 15 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,14 @@ def check_for_openmp():
return not result


def get_requirements():
fname = f"{os.path.dirname(os.path.realpath(__file__))}/requirements.txt"
with open(fname) as f:
install_requires = f.read().splitlines()
return install_requires


if __name__ == '__main__':
openmp_enabled = check_for_openmp()

setup(
name='qstack',
version=get_git_version_hash(),
description='Stack of codes for dedicated pre- and post-processing tasks for Quantum Machine Learning',
url='https://github.com/lcmd-epfl/Q-stack',
python_requires='==3.9.*',
install_requires=get_requirements(),
packages=setuptools.find_packages(exclude=['tests', 'examples']),
ext_modules=[Extension('qstack.regression.lib.manh',
['qstack/regression/lib/manh.c'],
extra_compile_args=['-fopenmp', '-std=gnu11'] if openmp_enabled else ['-std=gnu11'],
extra_link_args=['-lgomp'] if openmp_enabled else [])
],
include_package_data=True,
package_data={'': ['regression/lib/manh.c', 'spahm/rho/basis_opt/*.bas']},
)
Empty file modified tests/test_global.py
100644 → 100755
Empty file.
Empty file modified tests/test_opt.py
100644 → 100755
Empty file.
3 changes: 2 additions & 1 deletion tests/test_otpd.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3

import os
import numpy as np
from qstack import compound, fields

def test_hf_otpd():
Expand All @@ -9,7 +10,7 @@ def test_hf_otpd():
mol = compound.xyz_to_mol(path+'/data/H2O.xyz', 'def2svp', charge=0, spin=0)
dm = fields.dm.get_converged_dm(mol, xc="pbe")
otpd, grid = fields.hf_otpd.hf_otpd(mol, dm, return_all=True)
assert(abs(otpd @ grid.weights-20.190382555868)<1e-10)
briling marked this conversation as resolved.
Show resolved Hide resolved
assert np.allclose(otpd @ grid.weights, 20.190382555868)


if __name__ == '__main__':
Expand Down
Empty file modified tests/test_spahm_b.py
100644 → 100755
Empty file.
Empty file modified tests/test_utils.py
100644 → 100755
Empty file.
Loading