From 4bfb1c1d0ed990b5163b31732d78d449a9697cfe Mon Sep 17 00:00:00 2001 From: Nikhil Shenoy Date: Fri, 9 Feb 2024 01:29:12 +0000 Subject: [PATCH 01/28] Updated dummy dataset --- src/openqdc/datasets/dummy.py | 67 ++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/src/openqdc/datasets/dummy.py b/src/openqdc/datasets/dummy.py index c87e03d..80fcb4f 100644 --- a/src/openqdc/datasets/dummy.py +++ b/src/openqdc/datasets/dummy.py @@ -1,15 +1,12 @@ -import numpy as np # noqa -from numpy import array -from sklearn.utils import Bunch +import numpy as np from openqdc.datasets.base import BaseDataset -from openqdc.utils.atomization_energies import IsolatedAtomEnergyFactory from openqdc.utils.constants import NOT_DEFINED class Dummy(BaseDataset): """ - Dummy dataset + Dummy dataset for testing. """ __name__ = "dummy" @@ -30,21 +27,26 @@ def _stats(self): return { "formation": { "energy": { - "mean": array([[-12.94348027, -9.83037297]]), - "std": array([[4.39971409, 3.3574188]]), + "mean": np.array([[-12.94348027, -9.83037297]]), + "std": np.array([[4.39971409, 3.3574188]]), }, "forces": NOT_DEFINED, }, "total": { "energy": { - "mean": array([[-89.44242, -1740.5336]]), - "std": array([[29.599571, 791.48663]]), + "mean": np.array([[-89.44242, -1740.5336]]), + "std": np.array([[29.599571, 791.48663]]), }, "forces": NOT_DEFINED, }, } - def __init__(self, energy_unit=None, distance_unit=None, cache_dir=None) -> None: + def __init__( + self, + energy_unit=None, + distance_unit=None, + cache_dir=None, + ) -> None: try: super().__init__(energy_unit=energy_unit, distance_unit=distance_unit, cache_dir=cache_dir) @@ -52,10 +54,33 @@ def __init__(self, energy_unit=None, distance_unit=None, cache_dir=None) -> None pass self._set_isolated_atom_energies() self.setup_dummy() - + def setup_dummy(self): - self._n_atoms = np.array([np.random.randint(1, 100) for _ in range(self.__len__())]) - self.__average_nb_atoms__ = self._n_atoms.mean() + n_atoms = np.array([np.random.randint(1, 100) for _ in range(len(self))]) + position_idx_range = np.concatenate([[0], np.cumsum(n_atoms)]).repeat(2)[1:-1].reshape(-1, 2) + atomic_inputs = np.concatenate([np.concatenate([ + # z, c, x, y, z + np.random.randint(1, 100, size=(size, 1)), + np.random.randint(-1, 2, size=(size, 1)), + np.random.randn(size, 3) + ], axis=1) for size in n_atoms], axis=0) # (sum(n_atoms), 5) + name=[f'dummy_{i}' for i in range(len(self))] + subset=["dummy" for i in range(len(self))] + energies = np.random.rand(len(self), len(self.__energy_methods__)) + forces = np.concatenate([ + np.random.randn(size, 3, len(self.__force_methods__)) * 100 + for size in n_atoms + ]) + self.data = dict( + n_atoms=n_atoms, + position_idx_range=position_idx_range, + name=name, + atomic_inputs=atomic_inputs, + subset=subset, + energies=energies, + forces=forces, + ) + self.__average_nb_atoms__ = self.data["n_atoms"].mean() def is_preprocessed(self): return True @@ -65,19 +90,3 @@ def read_raw_entries(self): def __len__(self): return 9999 - - def __getitem__(self, idx: int): - shift = IsolatedAtomEnergyFactory.max_charge - size = self._n_atoms[idx] - z = np.random.randint(1, 100, size) - c = np.random.randint(-1, 2, size) - return Bunch( - positions=np.random.rand(size, 3) * 10, - atomic_numbers=z, - charges=c, - e0=self.__isolated_atom_energies__[..., z, c + shift].T, - energies=np.random.randn(len(self.__energy_methods__)), - name="dummy_{}".format(idx), - subset="dummy", - forces=(np.random.randn(size, 3, len(self.__force_methods__)) * 100), - ) From 862dc608657fca3c82beba0aa9b1254562c5aed9 Mon Sep 17 00:00:00 2001 From: Nikhil Shenoy Date: Fri, 9 Feb 2024 01:29:53 +0000 Subject: [PATCH 02/28] ran pre-commit on dummy --- src/openqdc/datasets/dummy.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/openqdc/datasets/dummy.py b/src/openqdc/datasets/dummy.py index 80fcb4f..2f421a8 100644 --- a/src/openqdc/datasets/dummy.py +++ b/src/openqdc/datasets/dummy.py @@ -54,23 +54,29 @@ def __init__( pass self._set_isolated_atom_energies() self.setup_dummy() - + def setup_dummy(self): n_atoms = np.array([np.random.randint(1, 100) for _ in range(len(self))]) position_idx_range = np.concatenate([[0], np.cumsum(n_atoms)]).repeat(2)[1:-1].reshape(-1, 2) - atomic_inputs = np.concatenate([np.concatenate([ - # z, c, x, y, z - np.random.randint(1, 100, size=(size, 1)), - np.random.randint(-1, 2, size=(size, 1)), - np.random.randn(size, 3) - ], axis=1) for size in n_atoms], axis=0) # (sum(n_atoms), 5) - name=[f'dummy_{i}' for i in range(len(self))] - subset=["dummy" for i in range(len(self))] + atomic_inputs = np.concatenate( + [ + np.concatenate( + [ + # z, c, x, y, z + np.random.randint(1, 100, size=(size, 1)), + np.random.randint(-1, 2, size=(size, 1)), + np.random.randn(size, 3), + ], + axis=1, + ) + for size in n_atoms + ], + axis=0, + ) # (sum(n_atoms), 5) + name = [f"dummy_{i}" for i in range(len(self))] + subset = ["dummy" for i in range(len(self))] energies = np.random.rand(len(self), len(self.__energy_methods__)) - forces = np.concatenate([ - np.random.randn(size, 3, len(self.__force_methods__)) * 100 - for size in n_atoms - ]) + forces = np.concatenate([np.random.randn(size, 3, len(self.__force_methods__)) * 100 for size in n_atoms]) self.data = dict( n_atoms=n_atoms, position_idx_range=position_idx_range, From f8a6f0fc9833e2ed38375231323a453db08c1519 Mon Sep 17 00:00:00 2001 From: FNTwin Date: Thu, 29 Feb 2024 07:15:55 -0700 Subject: [PATCH 03/28] Download and upload progress. No init method --- src/openqdc/datasets/base.py | 114 +++++++++++++--------- src/openqdc/utils/atomization_energies.py | 1 - src/openqdc/utils/io.py | 46 +++++++-- src/openqdc/utils/package_utils.py | 2 - 4 files changed, 107 insertions(+), 56 deletions(-) diff --git a/src/openqdc/datasets/base.py b/src/openqdc/datasets/base.py index adf9ae6..f0c1ab5 100644 --- a/src/openqdc/datasets/base.py +++ b/src/openqdc/datasets/base.py @@ -82,6 +82,10 @@ def read_qc_archive_h5( class BaseDataset: + """ + Base class for datasets in the openQDC package. + """ + __energy_methods__ = [] __force_methods__ = [] energy_target_names = [] @@ -124,6 +128,14 @@ def _post_init( self._set_units(energy_unit, distance_unit) self._convert_data() self._set_isolated_atom_energies() + + @classmethod + def no_init(cls): + """ + Class method to avoid the __init__ method to be called when the class is instanciated. + Useful for debugging purposes or preprocessing data. + """ + return cls.__new__(cls) def _convert_data(self): logger.info( @@ -366,9 +378,9 @@ def _convert_on_loading(self, x, key): return x def read_preprocess(self, overwrite_local_cache=False): - logger.info("Reading preprocessed data") + logger.info("Reading preprocessed data.") logger.info( - f"{self.__name__} data with the following units:\n\ + f"Dataset {self.__name__} with the following units:\n\ Energy: {self.energy_unit},\n\ Distance: {self.distance_unit},\n\ Forces: {self.force_unit if self.__force_methods__ else 'None'}" @@ -380,7 +392,6 @@ def read_preprocess(self, overwrite_local_cache=False): self.data[key] = np.memmap(filename, mode="r", dtype=self.data_types[key]).reshape(self.data_shapes[key]) filename = p_join(self.preprocess_path, "props.pkl") - pull_locally(filename, overwrite=overwrite_local_cache) with open(filename, "rb") as f: tmp = pkl.load(f) for key in ["name", "subset", "n_atoms"]: @@ -519,49 +530,19 @@ def wrapper(idx): if return_idxs: datum["idxs"] = idxs return datum - - def __len__(self): - return self.data["energies"].shape[0] - - def __smiles_converter__(self, x): - """util function to convert string to smiles: useful if the smiles is - encoded in a different format than its display format + + def as_iter(self, atoms: bool = False): """ - return x - - def __getitem__(self, idx: int): - shift = IsolatedAtomEnergyFactory.max_charge - p_start, p_end = self.data["position_idx_range"][idx] - input = self.data["atomic_inputs"][p_start:p_end] - z, c, positions, energies = ( - np.array(input[:, 0], dtype=np.int32), - np.array(input[:, 1], dtype=np.int32), - np.array(input[:, -3:], dtype=np.float32), - np.array(self.data["energies"][idx], dtype=np.float32), - ) - name = self.__smiles_converter__(self.data["name"][idx]) - subset = self.data["subset"][idx] - - if "forces" in self.data: - forces = np.array(self.data["forces"][p_start:p_end], dtype=np.float32) - else: - forces = None - return Bunch( - positions=positions, - atomic_numbers=z, - charges=c, - e0=self.__isolated_atom_energies__[..., z, c + shift].T, - energies=energies, - name=name, - subset=subset, - forces=forces, - ) - - def __str__(self): - return f"{self.__name__}" - - def __repr__(self): - return f"{self.__name__}" + Return the dataset as an iterator. + + Parameters + ---------- + atoms : bool, optional + Whether to return the items as ASE atoms object, by default False + """ + func = self.get_ase_atoms if atoms else self.__getitem__ + for i in range(len(self)): + yield func(i) @property def _stats(self): @@ -620,3 +601,46 @@ def get_statistics(self, normalization: str = "formation", return_none: bool = T for key2 in selected_stats[key]: selected_stats[key][key2] = self.convert_energy(selected_stats[key][key2]) return selected_stats + + def __str__(self): + return f"{self.__name__}" + + def __repr__(self): + return f"{self.__name__}" + + def __len__(self): + return self.data["energies"].shape[0] + + def __smiles_converter__(self, x): + """util function to convert string to smiles: useful if the smiles is + encoded in a different format than its display format + """ + return x + + def __getitem__(self, idx: int): + shift = IsolatedAtomEnergyFactory.max_charge + p_start, p_end = self.data["position_idx_range"][idx] + input = self.data["atomic_inputs"][p_start:p_end] + z, c, positions, energies = ( + np.array(input[:, 0], dtype=np.int32), + np.array(input[:, 1], dtype=np.int32), + np.array(input[:, -3:], dtype=np.float32), + np.array(self.data["energies"][idx], dtype=np.float32), + ) + name = self.__smiles_converter__(self.data["name"][idx]) + subset = self.data["subset"][idx] + + if "forces" in self.data: + forces = np.array(self.data["forces"][p_start:p_end], dtype=np.float32) + else: + forces = None + return Bunch( + positions=positions, + atomic_numbers=z, + charges=c, + e0=self.__isolated_atom_energies__[..., z, c + shift].T, + energies=energies, + name=name, + subset=subset, + forces=forces, + ) \ No newline at end of file diff --git a/src/openqdc/utils/atomization_energies.py b/src/openqdc/utils/atomization_energies.py index 746ff66..7325de3 100644 --- a/src/openqdc/utils/atomization_energies.py +++ b/src/openqdc/utils/atomization_energies.py @@ -12,7 +12,6 @@ EF_KEY: TypeAlias = Tuple[str, int] -# didn t calculate for Pd, Pt, Mo, Ni, Fe, Cu, see DESS atomic_numbers = {} chemical_symbols = np.array( [ diff --git a/src/openqdc/utils/io.py b/src/openqdc/utils/io.py index 2503031..c6e3280 100644 --- a/src/openqdc/utils/io.py +++ b/src/openqdc/utils/io.py @@ -9,9 +9,13 @@ from fsspec.implementations.local import LocalFileSystem from gcsfs import GCSFileSystem from rdkit.Chem import MolFromXYZFile - -gcp_filesys = fsspec.filesystem("gs") -gcp_filesys_public = fsspec.filesystem("https") +import fsspec +from fsspec.callbacks import TqdmCallback +from tqdm import tqdm +from loguru import logger + +gcp_filesys = fsspec.filesystem("gs") # entry point for google bucket (need gsutil permission) +gcp_filesys_public = fsspec.filesystem("https") # public API for download local_filesys = LocalFileSystem() _OPENQDC_CACHE_DIR = ( @@ -45,28 +49,51 @@ def get_local_cache() -> str: def get_remote_cache(write_access=False) -> str: + """ + Returns the entry point based on the write access. + """ if write_access: remote_cache = "gs://qmdata-public/openqdc" else: remote_cache = "https://storage.googleapis.com/qmdata-public/openqdc" return remote_cache - def push_remote(local_path, overwrite=True): + """ + Attempt to push file to remote gs path + """ remote_path = local_path.replace(get_local_cache(), get_remote_cache(write_access=overwrite)) gcp_filesys.mkdirs(os.path.dirname(remote_path), exist_ok=False) - print(f"Pushing {local_path} file to {remote_path}, ({gcp_filesys.exists(os.path.dirname(remote_path))})") + #print(f"Pushing {local_path} file to {remote_path}, ({gcp_filesys.exists(os.path.dirname(remote_path))})") if not gcp_filesys.exists(remote_path) or overwrite: - gcp_filesys.put_file(local_path, remote_path) + gcp_filesys.put_file(local_path, remote_path, + callback=TqdmCallback( + tqdm_kwargs={ + "ascii": " ▖▘▝▗▚▞-", + "desc" : f"Uploading {os.path.basename(remote_path)}", + "unit" : "B", + }, + ) + ) return remote_path def pull_locally(local_path, overwrite=False): + """ + Retrieve file from remote gs path or local cache + """ remote_path = local_path.replace(get_local_cache(), get_remote_cache()) os.makedirs(os.path.dirname(local_path), exist_ok=True) if not os.path.exists(local_path) or overwrite: - # print(f"Pulling {remote_path} file to {local_path}") - gcp_filesys_public.get_file(remote_path, local_path) + gcp_filesys_public.get_file(remote_path, local_path, + callback=TqdmCallback( + tqdm_kwargs={ + "ascii": " ▖▘▝▗▚▞-", + "desc" : f"Downloading {os.path.basename(remote_path)}", + "unit" : "B", + }, + ) + ) return local_path @@ -161,6 +188,9 @@ def load_json(path): def load_xyz(path): + """ + Load XYZ file using RDKit + """ return MolFromXYZFile(path) diff --git a/src/openqdc/utils/package_utils.py b/src/openqdc/utils/package_utils.py index c7b8aac..c64653f 100644 --- a/src/openqdc/utils/package_utils.py +++ b/src/openqdc/utils/package_utils.py @@ -116,7 +116,6 @@ def get_dir(): if _hub_dir is not None: return _hub_dir - # return os.path.join(_get_torch_home(), 'hub') def set_dir(d): @@ -127,4 +126,3 @@ def set_dir(d): d (str): path to a local folder to save downloaded models & weights. """ global _hub_dir - # _hub_dir = os.path.expanduser(d) From c15960392cee6c4953408e335ca90afcbbb55936 Mon Sep 17 00:00:00 2001 From: FNTwin Date: Thu, 29 Feb 2024 07:41:55 -0700 Subject: [PATCH 04/28] Basic versioning, refactor src->openqdc, updated .toml --- {src/openqdc => openqdc}/__init__.py | 3 ++ openqdc/_version.py | 13 ++++++++ {src/openqdc => openqdc}/datasets/__init__.py | 0 {src/openqdc => openqdc}/datasets/ani.py | 0 {src/openqdc => openqdc}/datasets/base.py | 0 {src/openqdc => openqdc}/datasets/comp6.py | 0 {src/openqdc => openqdc}/datasets/dess.py | 0 {src/openqdc => openqdc}/datasets/dummy.py | 0 {src/openqdc => openqdc}/datasets/gdml.py | 0 {src/openqdc => openqdc}/datasets/geom.py | 0 {src/openqdc => openqdc}/datasets/iso_17.py | 0 .../datasets/molecule3d.py | 0 {src/openqdc => openqdc}/datasets/nabladft.py | 0 .../datasets/orbnet_denali.py | 0 {src/openqdc => openqdc}/datasets/pcqm.py | 0 {src/openqdc => openqdc}/datasets/qm7x.py | 0 {src/openqdc => openqdc}/datasets/qmugs.py | 0 {src/openqdc => openqdc}/datasets/sn2_rxn.py | 0 .../datasets/solvated_peptides.py | 0 {src/openqdc => openqdc}/datasets/spice.py | 0 {src/openqdc => openqdc}/datasets/tmqm.py | 0 .../datasets/transition1x.py | 0 .../datasets/waterclusters3_30.py | 0 .../raws/config_factory.py | 0 {src/openqdc => openqdc}/raws/fetch.py | 0 {src/openqdc => openqdc}/raws/pubchemqc.py | 0 {src/openqdc => openqdc}/utils/__init__.py | 0 .../utils/atomization_energies.py | 0 {src/openqdc => openqdc}/utils/constants.py | 0 {src/openqdc => openqdc}/utils/exceptions.py | 0 {src/openqdc => openqdc}/utils/io.py | 0 {src/openqdc => openqdc}/utils/molecule.py | 0 .../utils/package_utils.py | 0 {src/openqdc => openqdc}/utils/preprocess.py | 0 {src/openqdc => openqdc}/utils/units.py | 0 pyproject.toml | 31 +++++++++++++++++-- 36 files changed, 45 insertions(+), 2 deletions(-) rename {src/openqdc => openqdc}/__init__.py (95%) create mode 100644 openqdc/_version.py rename {src/openqdc => openqdc}/datasets/__init__.py (100%) rename {src/openqdc => openqdc}/datasets/ani.py (100%) rename {src/openqdc => openqdc}/datasets/base.py (100%) rename {src/openqdc => openqdc}/datasets/comp6.py (100%) rename {src/openqdc => openqdc}/datasets/dess.py (100%) rename {src/openqdc => openqdc}/datasets/dummy.py (100%) rename {src/openqdc => openqdc}/datasets/gdml.py (100%) rename {src/openqdc => openqdc}/datasets/geom.py (100%) rename {src/openqdc => openqdc}/datasets/iso_17.py (100%) rename {src/openqdc => openqdc}/datasets/molecule3d.py (100%) rename {src/openqdc => openqdc}/datasets/nabladft.py (100%) rename {src/openqdc => openqdc}/datasets/orbnet_denali.py (100%) rename {src/openqdc => openqdc}/datasets/pcqm.py (100%) rename {src/openqdc => openqdc}/datasets/qm7x.py (100%) rename {src/openqdc => openqdc}/datasets/qmugs.py (100%) rename {src/openqdc => openqdc}/datasets/sn2_rxn.py (100%) rename {src/openqdc => openqdc}/datasets/solvated_peptides.py (100%) rename {src/openqdc => openqdc}/datasets/spice.py (100%) rename {src/openqdc => openqdc}/datasets/tmqm.py (100%) rename {src/openqdc => openqdc}/datasets/transition1x.py (100%) rename {src/openqdc => openqdc}/datasets/waterclusters3_30.py (100%) rename {src/openqdc => openqdc}/raws/config_factory.py (100%) rename {src/openqdc => openqdc}/raws/fetch.py (100%) rename {src/openqdc => openqdc}/raws/pubchemqc.py (100%) rename {src/openqdc => openqdc}/utils/__init__.py (100%) rename {src/openqdc => openqdc}/utils/atomization_energies.py (100%) rename {src/openqdc => openqdc}/utils/constants.py (100%) rename {src/openqdc => openqdc}/utils/exceptions.py (100%) rename {src/openqdc => openqdc}/utils/io.py (100%) rename {src/openqdc => openqdc}/utils/molecule.py (100%) rename {src/openqdc => openqdc}/utils/package_utils.py (100%) rename {src/openqdc => openqdc}/utils/preprocess.py (100%) rename {src/openqdc => openqdc}/utils/units.py (100%) diff --git a/src/openqdc/__init__.py b/openqdc/__init__.py similarity index 95% rename from src/openqdc/__init__.py rename to openqdc/__init__.py index 87fc457..040fa06 100644 --- a/src/openqdc/__init__.py +++ b/openqdc/__init__.py @@ -8,6 +8,7 @@ # Dictionary of objects to lazily import; maps the object's name to its module path _lazy_imports_obj = { + "__version__": "openqdc._version", "ANI1": "openqdc.datasets.ani", "ANI1CCX": "openqdc.datasets.ani", "ANI1X": "openqdc.datasets.ani", @@ -62,3 +63,5 @@ def __dir__(): # These types are imported lazily at runtime, but we need to tell type # checkers what they are. from .datasets import * + from ._version import __version__ + from .utils import * diff --git a/openqdc/_version.py b/openqdc/_version.py new file mode 100644 index 0000000..0faccd4 --- /dev/null +++ b/openqdc/_version.py @@ -0,0 +1,13 @@ +try: + from importlib.metadata import version + from importlib.metadata import PackageNotFoundError +except ModuleNotFoundError: + # Try backported to PY<38 `importlib_metadata`. + from importlib_metadata import version + from importlib_metadata import PackageNotFoundError + +try: + __version__ = version("openqdc") +except PackageNotFoundError: + # package is not installed + __version__ = "dev" \ No newline at end of file diff --git a/src/openqdc/datasets/__init__.py b/openqdc/datasets/__init__.py similarity index 100% rename from src/openqdc/datasets/__init__.py rename to openqdc/datasets/__init__.py diff --git a/src/openqdc/datasets/ani.py b/openqdc/datasets/ani.py similarity index 100% rename from src/openqdc/datasets/ani.py rename to openqdc/datasets/ani.py diff --git a/src/openqdc/datasets/base.py b/openqdc/datasets/base.py similarity index 100% rename from src/openqdc/datasets/base.py rename to openqdc/datasets/base.py diff --git a/src/openqdc/datasets/comp6.py b/openqdc/datasets/comp6.py similarity index 100% rename from src/openqdc/datasets/comp6.py rename to openqdc/datasets/comp6.py diff --git a/src/openqdc/datasets/dess.py b/openqdc/datasets/dess.py similarity index 100% rename from src/openqdc/datasets/dess.py rename to openqdc/datasets/dess.py diff --git a/src/openqdc/datasets/dummy.py b/openqdc/datasets/dummy.py similarity index 100% rename from src/openqdc/datasets/dummy.py rename to openqdc/datasets/dummy.py diff --git a/src/openqdc/datasets/gdml.py b/openqdc/datasets/gdml.py similarity index 100% rename from src/openqdc/datasets/gdml.py rename to openqdc/datasets/gdml.py diff --git a/src/openqdc/datasets/geom.py b/openqdc/datasets/geom.py similarity index 100% rename from src/openqdc/datasets/geom.py rename to openqdc/datasets/geom.py diff --git a/src/openqdc/datasets/iso_17.py b/openqdc/datasets/iso_17.py similarity index 100% rename from src/openqdc/datasets/iso_17.py rename to openqdc/datasets/iso_17.py diff --git a/src/openqdc/datasets/molecule3d.py b/openqdc/datasets/molecule3d.py similarity index 100% rename from src/openqdc/datasets/molecule3d.py rename to openqdc/datasets/molecule3d.py diff --git a/src/openqdc/datasets/nabladft.py b/openqdc/datasets/nabladft.py similarity index 100% rename from src/openqdc/datasets/nabladft.py rename to openqdc/datasets/nabladft.py diff --git a/src/openqdc/datasets/orbnet_denali.py b/openqdc/datasets/orbnet_denali.py similarity index 100% rename from src/openqdc/datasets/orbnet_denali.py rename to openqdc/datasets/orbnet_denali.py diff --git a/src/openqdc/datasets/pcqm.py b/openqdc/datasets/pcqm.py similarity index 100% rename from src/openqdc/datasets/pcqm.py rename to openqdc/datasets/pcqm.py diff --git a/src/openqdc/datasets/qm7x.py b/openqdc/datasets/qm7x.py similarity index 100% rename from src/openqdc/datasets/qm7x.py rename to openqdc/datasets/qm7x.py diff --git a/src/openqdc/datasets/qmugs.py b/openqdc/datasets/qmugs.py similarity index 100% rename from src/openqdc/datasets/qmugs.py rename to openqdc/datasets/qmugs.py diff --git a/src/openqdc/datasets/sn2_rxn.py b/openqdc/datasets/sn2_rxn.py similarity index 100% rename from src/openqdc/datasets/sn2_rxn.py rename to openqdc/datasets/sn2_rxn.py diff --git a/src/openqdc/datasets/solvated_peptides.py b/openqdc/datasets/solvated_peptides.py similarity index 100% rename from src/openqdc/datasets/solvated_peptides.py rename to openqdc/datasets/solvated_peptides.py diff --git a/src/openqdc/datasets/spice.py b/openqdc/datasets/spice.py similarity index 100% rename from src/openqdc/datasets/spice.py rename to openqdc/datasets/spice.py diff --git a/src/openqdc/datasets/tmqm.py b/openqdc/datasets/tmqm.py similarity index 100% rename from src/openqdc/datasets/tmqm.py rename to openqdc/datasets/tmqm.py diff --git a/src/openqdc/datasets/transition1x.py b/openqdc/datasets/transition1x.py similarity index 100% rename from src/openqdc/datasets/transition1x.py rename to openqdc/datasets/transition1x.py diff --git a/src/openqdc/datasets/waterclusters3_30.py b/openqdc/datasets/waterclusters3_30.py similarity index 100% rename from src/openqdc/datasets/waterclusters3_30.py rename to openqdc/datasets/waterclusters3_30.py diff --git a/src/openqdc/raws/config_factory.py b/openqdc/raws/config_factory.py similarity index 100% rename from src/openqdc/raws/config_factory.py rename to openqdc/raws/config_factory.py diff --git a/src/openqdc/raws/fetch.py b/openqdc/raws/fetch.py similarity index 100% rename from src/openqdc/raws/fetch.py rename to openqdc/raws/fetch.py diff --git a/src/openqdc/raws/pubchemqc.py b/openqdc/raws/pubchemqc.py similarity index 100% rename from src/openqdc/raws/pubchemqc.py rename to openqdc/raws/pubchemqc.py diff --git a/src/openqdc/utils/__init__.py b/openqdc/utils/__init__.py similarity index 100% rename from src/openqdc/utils/__init__.py rename to openqdc/utils/__init__.py diff --git a/src/openqdc/utils/atomization_energies.py b/openqdc/utils/atomization_energies.py similarity index 100% rename from src/openqdc/utils/atomization_energies.py rename to openqdc/utils/atomization_energies.py diff --git a/src/openqdc/utils/constants.py b/openqdc/utils/constants.py similarity index 100% rename from src/openqdc/utils/constants.py rename to openqdc/utils/constants.py diff --git a/src/openqdc/utils/exceptions.py b/openqdc/utils/exceptions.py similarity index 100% rename from src/openqdc/utils/exceptions.py rename to openqdc/utils/exceptions.py diff --git a/src/openqdc/utils/io.py b/openqdc/utils/io.py similarity index 100% rename from src/openqdc/utils/io.py rename to openqdc/utils/io.py diff --git a/src/openqdc/utils/molecule.py b/openqdc/utils/molecule.py similarity index 100% rename from src/openqdc/utils/molecule.py rename to openqdc/utils/molecule.py diff --git a/src/openqdc/utils/package_utils.py b/openqdc/utils/package_utils.py similarity index 100% rename from src/openqdc/utils/package_utils.py rename to openqdc/utils/package_utils.py diff --git a/src/openqdc/utils/preprocess.py b/openqdc/utils/preprocess.py similarity index 100% rename from src/openqdc/utils/preprocess.py rename to openqdc/utils/preprocess.py diff --git a/src/openqdc/utils/units.py b/openqdc/utils/units.py similarity index 100% rename from src/openqdc/utils/units.py rename to openqdc/utils/units.py diff --git a/pyproject.toml b/pyproject.toml index e589cf3..d8c2135 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,34 @@ name = "openqdc" dynamic = ["version"] description = "ML ready Quantum Mechanical datasets" authors = [{ name = "Nikhil Shenoy", email = "nikhilshenoy98@gmail.com" }, - { name = "Prudencio Tossou", email = "tossouprudencio@gmail.com" }] + { name = "Prudencio Tossou", email = "tossouprudencio@gmail.com" }, + { name = "Cristian Gabellini", email = "cris.gabellini@gmail.com" }] +readme = "README.md" +requires-python = ">=3.8" +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Intended Audience :: Healthcare Industry", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Topic :: Scientific/Engineering :: Bio-Informatics", + "Topic :: Scientific/Engineering :: Information Analysis", + "Topic :: Scientific/Engineering :: Medical Science Apps.", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", +] + +[project.urls] +Website = "https://github.com/OpenDrugDiscovery" +"Source Code" = "https://github.com/OpenDrugDiscovery/openQDC" +"Bug Tracker" = "https://github.com/OpenDrugDiscovery/openQDC/issues" +Documentation = "https://github.com/OpenDrugDiscovery/openQDC" [tool.setuptools] include-package-data = true @@ -19,7 +46,7 @@ fallback_version = "dev" profile = "black" [tool.setuptools.packages.find] -where = ["src"] +where = ["."] include = ["openqdc", "openqdc.*"] exclude = [] namespaces = true From 77acba2e8ea532b12b3af044dc7303e4a8a6fc52 Mon Sep 17 00:00:00 2001 From: FNTwin Date: Thu, 29 Feb 2024 07:53:05 -0700 Subject: [PATCH 05/28] __init__.py clean --- openqdc/__init__.py | 70 ++++++++++++------- openqdc/datasets/__init__.py | 127 ++++++----------------------------- 2 files changed, 65 insertions(+), 132 deletions(-) diff --git a/openqdc/__init__.py b/openqdc/__init__.py index 040fa06..7fd3450 100644 --- a/openqdc/__init__.py +++ b/openqdc/__init__.py @@ -9,31 +9,33 @@ _lazy_imports_obj = { "__version__": "openqdc._version", - "ANI1": "openqdc.datasets.ani", - "ANI1CCX": "openqdc.datasets.ani", - "ANI1X": "openqdc.datasets.ani", - "Spice": "openqdc.datasets.spice", - "GEOM": "openqdc.datasets.geom", - "QMugs": "openqdc.datasets.qmugs", - "ISO17": "openqdc.datasets.iso_17", - "COMP6": "openqdc.datasets.comp6", - "GDML": "openqdc.datasets.gdml", - "Molecule3D": "openqdc.datasets.molecule3d", - "OrbnetDenali": "openqdc.datasets.orbnet_denali", - "SN2RXN": "openqdc.datasets.sn2_rxn", - "QM7X": "openqdc.datasets.qm7x", - "DESS": "openqdc.datasets.dess", - "NablaDFT": "openqdc.datasets.nabladft", - "SolvatedPeptides": "openqdc.datasets.solvated_peptides", - "WaterClusters": "openqdc.datasets.waterclusters3_30", - "TMQM": "openqdc.datasets.tmqm", - "Dummy": "openqdc.datasets.dummy", - "PCQM_B3LYP": "openqdc.datasets.pcqm", - "PCQM_PM6": "openqdc.datasets.pcqm", - "Transition1X": "openqdc.datasets.transition1x", + "BaseDataset" : "openqdc.datasets", + "ANI1": "openqdc.datasets", + "ANI1CCX": "openqdc.datasets", + "ANI1X": "openqdc.datasets", + "Spice": "openqdc.datasets", + "GEOM": "openqdc.datasets", + "QMugs": "openqdc.datasets", + "ISO17": "openqdc.datasets", + "COMP6": "openqdc.datasets", + "GDML": "openqdc.datasets", + "Molecule3D": "openqdc.datasets", + "OrbnetDenali": "openqdc.datasets", + "SN2RXN": "openqdc.datasets", + "QM7X": "openqdc.datasets", + "DESS": "openqdc.datasets", + "NablaDFT": "openqdc.datasets", + "SolvatedPeptides": "openqdc.datasets", + "WaterClusters": "openqdc.datasets", + "TMQM": "openqdc.datasets", + "Dummy": "openqdc.datasets", + "PCQM_B3LYP": "openqdc.datasets", + "PCQM_PM6": "openqdc.datasets", + "Transition1X": "openqdc.datasets", } -_lazy_imports_mod = {"datasets": "openqdc.datasets", "utils": "openqdc.utils"} +_lazy_imports_mod = {"datasets": "openqdc.datasets", + "utils": "openqdc.utils"} def __getattr__(name): @@ -62,6 +64,24 @@ def __dir__(): if TYPE_CHECKING or os.environ.get("OPENQDC_DISABLE_LAZY_LOADING", "0") == "1": # These types are imported lazily at runtime, but we need to tell type # checkers what they are. - from .datasets import * from ._version import __version__ - from .utils import * + from .datasets.ani import ANI1, ANI1CCX, ANI1X # noqa + from .datasets.comp6 import COMP6 # noqa + from .datasets.dess import DESS # noqa + from .datasets.dummy import Dummy # noqa + from .datasets.gdml import GDML # noqa + from .datasets.geom import GEOM # noqa + from .datasets.iso_17 import ISO17 # noqa + from .datasets.molecule3d import Molecule3D # noqa + from .datasets.nabladft import NablaDFT # noqa + from .datasets.orbnet_denali import OrbnetDenali # noqa + from .datasets.pcqm import PCQM_B3LYP, PCQM_PM6 # noqa + from .datasets.qm7x import QM7X # noqa + from .datasets.qmugs import QMugs # noqa + from .datasets.sn2_rxn import SN2RXN # noqa + from .datasets.solvated_peptides import SolvatedPeptides # noqa + from .datasets.spice import Spice # noqa + from .datasets.tmqm import TMQM # noqa + from .datasets.transition1x import Transition1X # noqa + from .datasets.waterclusters3_30 import WaterClusters # noqa + from .datasets.base import BaseDataset # noqa diff --git a/openqdc/datasets/__init__.py b/openqdc/datasets/__init__.py index d989935..36e5cd0 100644 --- a/openqdc/datasets/__init__.py +++ b/openqdc/datasets/__init__.py @@ -1,107 +1,20 @@ -import importlib -import os -from typing import TYPE_CHECKING # noqa F401 - -# The below lazy import logic is coming from openff-toolkit: -# https://github.com/openforcefield/openff-toolkit/blob/b52879569a0344878c40248ceb3bd0f90348076a/openff/toolkit/__init__.py#L44 - -# Dictionary of objects to lazily import; maps the object's name to its module path - -_lazy_imports_obj = { - "ANI1": "openqdc.datasets.ani", - "ANI1CCX": "openqdc.datasets.ani", - "ANI1X": "openqdc.datasets.ani", - "Spice": "openqdc.datasets.spice", - "GEOM": "openqdc.datasets.geom", - "QMugs": "openqdc.datasets.qmugs", - "ISO17": "openqdc.datasets.iso_17", - "COMP6": "openqdc.datasets.comp6", - "GDML": "openqdc.datasets.gdml", - "Molecule3D": "openqdc.datasets.molecule3d", - "OrbnetDenali": "openqdc.datasets.orbnet_denali", - "SN2RXN": "openqdc.datasets.sn2_rxn", - "QM7X": "openqdc.datasets.qm7x", - "DESS": "openqdc.datasets.dess", - "NablaDFT": "openqdc.datasets.nabladft", - "SolvatedPeptides": "openqdc.datasets.solvated_peptides", - "WaterClusters": "openqdc.datasets.waterclusters3_30", - "TMQM": "openqdc.datasets.tmqm", - "Dummy": "openqdc.datasets.dummy", - "PCQM_B3LYP": "openqdc.datasets.pcqm", - "PCQM_PM6": "openqdc.datasets.pcqm", - "Transition1X": "openqdc.datasets.transition1x", -} - -_lazy_imports_mod = {} - - -def __getattr__(name): - """Lazily import objects from _lazy_imports_obj or _lazy_imports_mod - - Note that this method is only called by Python if the name cannot be found - in the current module.""" - obj_mod = _lazy_imports_obj.get(name) - if obj_mod is not None: - mod = importlib.import_module(obj_mod) - return mod.__dict__[name] - - lazy_mod = _lazy_imports_mod.get(name) - if lazy_mod is not None: - return importlib.import_module(lazy_mod) - - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") - - -def __dir__(): - """Add _lazy_imports_obj and _lazy_imports_mod to dir()""" - keys = (*globals().keys(), *_lazy_imports_obj.keys(), *_lazy_imports_mod.keys()) - return sorted(keys) - - -if TYPE_CHECKING or os.environ.get("OPENQDC_DISABLE_LAZY_LOADING", "0") == "1": - # These types are imported lazily at runtime, but we need to tell type - # checkers what they are. - from .ani import ANI1, ANI1CCX, ANI1X # noqa - from .comp6 import COMP6 # noqa - from .dess import DESS # noqa - from .dummy import Dummy # noqa - from .gdml import GDML # noqa - from .geom import GEOM # noqa - from .iso_17 import ISO17 # noqa - from .molecule3d import Molecule3D # noqa - from .nabladft import NablaDFT # noqa - from .orbnet_denali import OrbnetDenali # noqa - from .pcqm import PCQM_B3LYP, PCQM_PM6 # noqa - from .qm7x import QM7X # noqa - from .qmugs import QMugs # noqa - from .sn2_rxn import SN2RXN # noqa - from .solvated_peptides import SolvatedPeptides # noqa - from .spice import Spice # noqa - from .tmqm import TMQM # noqa - from .transition1x import Transition1X # noqa - from .waterclusters3_30 import WaterClusters # noqa - - __all__ = [ - "ANI1", - "ANI1X", - "ANI1CCX", - "Spice", - "GEOM", - "QMugs", - "ISO17", - "COMP6", - "GDML", - "Molecule3D", - "OrbnetDenali", - "SN2RXN", - "QM7X", - "DESS", - "NablaDFT", - "SolvatedPeptides", - "WaterClusters", - "TMQM", - "PCQM_B3LYP", - "PCQM_PM6", - "Transition1X", - "Dummy", - ] +from .ani import ANI1, ANI1CCX, ANI1X # noqa +from .comp6 import COMP6 # noqa +from .dess import DESS # noqa +from .dummy import Dummy # noqa +from .gdml import GDML # noqa +from .geom import GEOM # noqa +from .iso_17 import ISO17 # noqa +from .molecule3d import Molecule3D # noqa +from .nabladft import NablaDFT # noqa +from .orbnet_denali import OrbnetDenali # noqa +from .pcqm import PCQM_B3LYP, PCQM_PM6 # noqa +from .qm7x import QM7X # noqa +from .qmugs import QMugs # noqa +from .sn2_rxn import SN2RXN # noqa +from .solvated_peptides import SolvatedPeptides # noqa +from .spice import Spice # noqa +from .tmqm import TMQM # noqa +from .transition1x import Transition1X # noqa +from .waterclusters3_30 import WaterClusters # noqa +from .base import BaseDataset # noqa \ No newline at end of file From 8b54153d138aa86cd168c60f440317d6588014d5 Mon Sep 17 00:00:00 2001 From: FNTwin Date: Thu, 29 Feb 2024 08:33:48 -0700 Subject: [PATCH 06/28] black + isort --- openqdc/__init__.py | 9 ++++----- openqdc/_version.py | 8 +++----- openqdc/datasets/__init__.py | 2 +- openqdc/datasets/base.py | 12 ++++++------ openqdc/utils/io.py | 38 +++++++++++++++++++----------------- 5 files changed, 34 insertions(+), 35 deletions(-) diff --git a/openqdc/__init__.py b/openqdc/__init__.py index 7fd3450..e4d9ac3 100644 --- a/openqdc/__init__.py +++ b/openqdc/__init__.py @@ -9,7 +9,7 @@ _lazy_imports_obj = { "__version__": "openqdc._version", - "BaseDataset" : "openqdc.datasets", + "BaseDataset": "openqdc.datasets", "ANI1": "openqdc.datasets", "ANI1CCX": "openqdc.datasets", "ANI1X": "openqdc.datasets", @@ -34,8 +34,7 @@ "Transition1X": "openqdc.datasets", } -_lazy_imports_mod = {"datasets": "openqdc.datasets", - "utils": "openqdc.utils"} +_lazy_imports_mod = {"datasets": "openqdc.datasets", "utils": "openqdc.utils"} def __getattr__(name): @@ -64,8 +63,9 @@ def __dir__(): if TYPE_CHECKING or os.environ.get("OPENQDC_DISABLE_LAZY_LOADING", "0") == "1": # These types are imported lazily at runtime, but we need to tell type # checkers what they are. - from ._version import __version__ + from ._version import __version__ # noqa from .datasets.ani import ANI1, ANI1CCX, ANI1X # noqa + from .datasets.base import BaseDataset # noqa from .datasets.comp6 import COMP6 # noqa from .datasets.dess import DESS # noqa from .datasets.dummy import Dummy # noqa @@ -84,4 +84,3 @@ def __dir__(): from .datasets.tmqm import TMQM # noqa from .datasets.transition1x import Transition1X # noqa from .datasets.waterclusters3_30 import WaterClusters # noqa - from .datasets.base import BaseDataset # noqa diff --git a/openqdc/_version.py b/openqdc/_version.py index 0faccd4..63dc510 100644 --- a/openqdc/_version.py +++ b/openqdc/_version.py @@ -1,13 +1,11 @@ try: - from importlib.metadata import version - from importlib.metadata import PackageNotFoundError + from importlib.metadata import PackageNotFoundError, version except ModuleNotFoundError: # Try backported to PY<38 `importlib_metadata`. - from importlib_metadata import version - from importlib_metadata import PackageNotFoundError + from importlib_metadata import PackageNotFoundError, version try: __version__ = version("openqdc") except PackageNotFoundError: # package is not installed - __version__ = "dev" \ No newline at end of file + __version__ = "dev" diff --git a/openqdc/datasets/__init__.py b/openqdc/datasets/__init__.py index 36e5cd0..3a6cef7 100644 --- a/openqdc/datasets/__init__.py +++ b/openqdc/datasets/__init__.py @@ -1,4 +1,5 @@ from .ani import ANI1, ANI1CCX, ANI1X # noqa +from .base import BaseDataset # noqa from .comp6 import COMP6 # noqa from .dess import DESS # noqa from .dummy import Dummy # noqa @@ -17,4 +18,3 @@ from .tmqm import TMQM # noqa from .transition1x import Transition1X # noqa from .waterclusters3_30 import WaterClusters # noqa -from .base import BaseDataset # noqa \ No newline at end of file diff --git a/openqdc/datasets/base.py b/openqdc/datasets/base.py index f0c1ab5..66cd42e 100644 --- a/openqdc/datasets/base.py +++ b/openqdc/datasets/base.py @@ -128,8 +128,8 @@ def _post_init( self._set_units(energy_unit, distance_unit) self._convert_data() self._set_isolated_atom_energies() - - @classmethod + + @classmethod def no_init(cls): """ Class method to avoid the __init__ method to be called when the class is instanciated. @@ -530,11 +530,11 @@ def wrapper(idx): if return_idxs: datum["idxs"] = idxs return datum - + def as_iter(self, atoms: bool = False): """ Return the dataset as an iterator. - + Parameters ---------- atoms : bool, optional @@ -607,7 +607,7 @@ def __str__(self): def __repr__(self): return f"{self.__name__}" - + def __len__(self): return self.data["energies"].shape[0] @@ -643,4 +643,4 @@ def __getitem__(self, idx: int): name=name, subset=subset, forces=forces, - ) \ No newline at end of file + ) diff --git a/openqdc/utils/io.py b/openqdc/utils/io.py index c6e3280..fa24480 100644 --- a/openqdc/utils/io.py +++ b/openqdc/utils/io.py @@ -6,16 +6,13 @@ import fsspec import h5py from ase.atoms import Atoms +from fsspec.callbacks import TqdmCallback from fsspec.implementations.local import LocalFileSystem from gcsfs import GCSFileSystem from rdkit.Chem import MolFromXYZFile -import fsspec -from fsspec.callbacks import TqdmCallback -from tqdm import tqdm -from loguru import logger - -gcp_filesys = fsspec.filesystem("gs") # entry point for google bucket (need gsutil permission) -gcp_filesys_public = fsspec.filesystem("https") # public API for download + +gcp_filesys = fsspec.filesystem("gs") # entry point for google bucket (need gsutil permission) +gcp_filesys_public = fsspec.filesystem("https") # public API for download local_filesys = LocalFileSystem() _OPENQDC_CACHE_DIR = ( @@ -58,22 +55,25 @@ def get_remote_cache(write_access=False) -> str: remote_cache = "https://storage.googleapis.com/qmdata-public/openqdc" return remote_cache + def push_remote(local_path, overwrite=True): """ Attempt to push file to remote gs path """ remote_path = local_path.replace(get_local_cache(), get_remote_cache(write_access=overwrite)) gcp_filesys.mkdirs(os.path.dirname(remote_path), exist_ok=False) - #print(f"Pushing {local_path} file to {remote_path}, ({gcp_filesys.exists(os.path.dirname(remote_path))})") + # print(f"Pushing {local_path} file to {remote_path}, ({gcp_filesys.exists(os.path.dirname(remote_path))})") if not gcp_filesys.exists(remote_path) or overwrite: - gcp_filesys.put_file(local_path, remote_path, + gcp_filesys.put_file( + local_path, + remote_path, callback=TqdmCallback( tqdm_kwargs={ "ascii": " ▖▘▝▗▚▞-", - "desc" : f"Uploading {os.path.basename(remote_path)}", - "unit" : "B", - }, - ) + "desc": f"Uploading {os.path.basename(remote_path)}", + "unit": "B", + }, + ), ) return remote_path @@ -85,14 +85,16 @@ def pull_locally(local_path, overwrite=False): remote_path = local_path.replace(get_local_cache(), get_remote_cache()) os.makedirs(os.path.dirname(local_path), exist_ok=True) if not os.path.exists(local_path) or overwrite: - gcp_filesys_public.get_file(remote_path, local_path, + gcp_filesys_public.get_file( + remote_path, + local_path, callback=TqdmCallback( tqdm_kwargs={ "ascii": " ▖▘▝▗▚▞-", - "desc" : f"Downloading {os.path.basename(remote_path)}", - "unit" : "B", - }, - ) + "desc": f"Downloading {os.path.basename(remote_path)}", + "unit": "B", + }, + ), ) return local_path From e6995a7da8c6d3d88268964d676953d35b2b75d7 Mon Sep 17 00:00:00 2001 From: FNTwin Date: Thu, 29 Feb 2024 11:10:54 -0700 Subject: [PATCH 07/28] DES fix, base utilies, CLI --- env.yml | 1 + openqdc/__init__.py | 6 +- openqdc/cli.py | 85 ++++++++++++++++++++++++++++ openqdc/datasets/__init__.py | 26 ++++++++- openqdc/datasets/base.py | 9 +++ openqdc/datasets/{dess.py => des.py} | 4 +- openqdc/utils/constants.py | 12 ++-- openqdc/utils/exceptions.py | 2 +- openqdc/utils/preprocess.py | 4 +- pyproject.toml | 3 + 10 files changed, 139 insertions(+), 13 deletions(-) create mode 100644 openqdc/cli.py rename openqdc/datasets/{dess.py => des.py} (98%) diff --git a/env.yml b/env.yml index a88b919..76d2c22 100644 --- a/env.yml +++ b/env.yml @@ -9,6 +9,7 @@ dependencies: - loguru - fsspec - gcsfs + - typer # Scientific - pandas diff --git a/openqdc/__init__.py b/openqdc/__init__.py index e4d9ac3..abf50ad 100644 --- a/openqdc/__init__.py +++ b/openqdc/__init__.py @@ -23,7 +23,7 @@ "OrbnetDenali": "openqdc.datasets", "SN2RXN": "openqdc.datasets", "QM7X": "openqdc.datasets", - "DESS": "openqdc.datasets", + "DES": "openqdc.datasets", "NablaDFT": "openqdc.datasets", "SolvatedPeptides": "openqdc.datasets", "WaterClusters": "openqdc.datasets", @@ -32,6 +32,7 @@ "PCQM_B3LYP": "openqdc.datasets", "PCQM_PM6": "openqdc.datasets", "Transition1X": "openqdc.datasets", + "AVAILABLE_DATASETS": "openqdc.datasets", } _lazy_imports_mod = {"datasets": "openqdc.datasets", "utils": "openqdc.utils"} @@ -64,10 +65,11 @@ def __dir__(): # These types are imported lazily at runtime, but we need to tell type # checkers what they are. from ._version import __version__ # noqa + from .datasets import AVAILABLE_DATASETS # noqa from .datasets.ani import ANI1, ANI1CCX, ANI1X # noqa from .datasets.base import BaseDataset # noqa from .datasets.comp6 import COMP6 # noqa - from .datasets.dess import DESS # noqa + from .datasets.des import DES # noqa from .datasets.dummy import Dummy # noqa from .datasets.gdml import GDML # noqa from .datasets.geom import GEOM # noqa diff --git a/openqdc/cli.py b/openqdc/cli.py new file mode 100644 index 0000000..72a57a3 --- /dev/null +++ b/openqdc/cli.py @@ -0,0 +1,85 @@ +import os +from typing import List, Optional + +import typer +from typing_extensions import Annotated +from openqdc import AVAILABLE_DATASETS +from loguru import logger +from prettytable import PrettyTable +from openqdc.raws.config_factory import DataConfigFactory +from openqdc.raws.fetch import DataDownloader + +app = typer.Typer(help="OpenQDC CLI") + +def exist_dataset(dataset): + if dataset not in AVAILABLE_DATASETS: + logger.error(f"{dataset} is not available. Please open an issue on Github for the team to look into it.") + return False + return True + +@app.command() +def download( + datasets: Annotated[ + List[str], + typer.Option( + help="List of datasets to download", + ), + ], + overwrite: Annotated[ + bool, + typer.Option( + help="Whether to overwrite the datasets", + ), + ] = False, + cache_dir : Annotated[ + Optional[str], + typer.Option( + help="Path to cache directory", + ), + ] = None, +): + """ + Download preprocessed datasets from openQDC. + """ + for dataset in list(map(lambda x : x.lower().replace("_",""),datasets)): + if exist_dataset(dataset): + if AVAILABLE_DATASETS[dataset].no_init().is_cached() and not overwrite: + logger.info(f"{dataset} is already cached. Skipping download") + else: + AVAILABLE_DATASETS[dataset](overwrite_local_cache=True, cache_dir=cache_dir) + +@app.command() +def datasets(): + """ + Print the available datasets. + """ + table = PrettyTable(['Name', 'Level of theories', 'Has forces'], max_width=25) + table._max_width={} + for dataset in AVAILABLE_DATASETS: + empty_dataset=AVAILABLE_DATASETS[dataset].no_init() + has_forces = False if not empty_dataset.__force_methods__ else True + table.add_row([dataset, ",".join(empty_dataset.__energy_methods__),has_forces]) + table.align="l" + print(table) + +@app.command() +def fetch( + datasets: Annotated[ + List[str], + typer.Option( + help="List of datasets to fetch", + ), + ], +): + """ + Download the raw datasets files from openQDC. + """ + if datasets[0] == "all": + dataset_names = DataConfigFactory.available_datasets + + for dataset_name in dataset_names: + dd = DataDownloader() + dd.from_name(dataset_name) + +if __name__ == "__main__": + app() \ No newline at end of file diff --git a/openqdc/datasets/__init__.py b/openqdc/datasets/__init__.py index 3a6cef7..7e5e0cf 100644 --- a/openqdc/datasets/__init__.py +++ b/openqdc/datasets/__init__.py @@ -1,7 +1,7 @@ from .ani import ANI1, ANI1CCX, ANI1X # noqa from .base import BaseDataset # noqa from .comp6 import COMP6 # noqa -from .dess import DESS # noqa +from .des import DES # noqa from .dummy import Dummy # noqa from .gdml import GDML # noqa from .geom import GEOM # noqa @@ -18,3 +18,27 @@ from .tmqm import TMQM # noqa from .transition1x import Transition1X # noqa from .waterclusters3_30 import WaterClusters # noqa + +AVAILABLE_DATASETS = { + "ani1": ANI1, + "ani1ccx": ANI1CCX, + "ani1x": ANI1X, + "comp6": COMP6, + "des": DES, + "gdml": GDML, + "geom": GEOM, + "iso17": ISO17, + "molecule3d": Molecule3D, + "nabladft": NablaDFT, + "orbnetdenali": OrbnetDenali, + "pcqmb3lyp": PCQM_B3LYP, + "pcqmpm6": PCQM_PM6, + "qm7x": QM7X, + "qmugs": QMugs, + "sn2rxn": SN2RXN, + "solvatedpeptides": SolvatedPeptides, + "spice": Spice, + "tmqm": TMQM, + "transition1x": Transition1X, + "watercluster": WaterClusters, +} diff --git a/openqdc/datasets/base.py b/openqdc/datasets/base.py index 66cd42e..c65fdbc 100644 --- a/openqdc/datasets/base.py +++ b/openqdc/datasets/base.py @@ -392,6 +392,7 @@ def read_preprocess(self, overwrite_local_cache=False): self.data[key] = np.memmap(filename, mode="r", dtype=self.data_types[key]).reshape(self.data_shapes[key]) filename = p_join(self.preprocess_path, "props.pkl") + pull_locally(filename, overwrite=overwrite_local_cache) with open(filename, "rb") as f: tmp = pkl.load(f) for key in ["name", "subset", "n_atoms"]: @@ -409,6 +410,14 @@ def is_preprocessed(self): predicats += [copy_exists(p_join(self.preprocess_path, "props.pkl"))] return all(predicats) + def is_cached(self): + """ + Check if the dataset is cached locally. + """ + predicats = [os.path.exists(p_join(self.preprocess_path, f"{key}.mmap")) for key in self.data_keys] + predicats += [os.path.exists(p_join(self.preprocess_path, "props.pkl"))] + return all(predicats) + def is_preprocessed_statistics(self): return bool(copy_exists(p_join(self.preprocess_path, "stats.pkl"))) diff --git a/openqdc/datasets/dess.py b/openqdc/datasets/des.py similarity index 98% rename from openqdc/datasets/dess.py rename to openqdc/datasets/des.py index 80b1e1c..337a8e8 100644 --- a/openqdc/datasets/dess.py +++ b/openqdc/datasets/des.py @@ -32,8 +32,8 @@ def read_mol(mol_path, smiles, subset, targets): return res -class DESS(BaseDataset): - __name__ = "dess" +class DES(BaseDataset): + __name__ = "des" __energy_unit__ = "hartree" __distance_unit__ = "ang" __forces_unit__ = "hartree/ang" diff --git a/openqdc/utils/constants.py b/openqdc/utils/constants.py index 7bf570b..642eb49 100644 --- a/openqdc/utils/constants.py +++ b/openqdc/utils/constants.py @@ -1,12 +1,14 @@ -NB_ATOMIC_FEATURES = 5 +from typing import Final, List -MAX_ATOMIC_NUMBER = 119 +NB_ATOMIC_FEATURES: Final[int] = 5 -HAR2EV = 27.211386246 +MAX_ATOMIC_NUMBER: Final[int] = 119 -BOHR2ANG = 0.52917721092 +HAR2EV: Final[float] = 27.211386246 -POSSIBLE_NORMALIZATION = ["formation", "total", "inter"] +BOHR2ANG: Final[float] = 0.52917721092 + +POSSIBLE_NORMALIZATION: Final[List[str]] = ["formation", "total", "inter"] NOT_DEFINED = { "mean": None, diff --git a/openqdc/utils/exceptions.py b/openqdc/utils/exceptions.py index 246d01c..e564a2c 100644 --- a/openqdc/utils/exceptions.py +++ b/openqdc/utils/exceptions.py @@ -60,7 +60,7 @@ def __init__(self, in_unit, out_unit): class ConversionAlreadyDefined(ConversionNotDefinedError): - """Raised when a conversion is not defined""" + """Raised when a conversion is already defined""" _error_message = """ Conversion from {in_unit} to {out_unit} is alread defined in the conversion registry. diff --git a/openqdc/utils/preprocess.py b/openqdc/utils/preprocess.py index b34499e..9e55412 100644 --- a/openqdc/utils/preprocess.py +++ b/openqdc/utils/preprocess.py @@ -9,7 +9,7 @@ datasets.ANI1CCX, datasets.ANI1X, datasets.COMP6, - datasets.DESS, + datasets.DES, datasets.GDML, datasets.GEOM, datasets.ISO17, @@ -40,7 +40,7 @@ def preprocess(dataset): else: data_class = options_map[dataset] - data_class().preprocess(overwrite=False) + data_class.no_init().preprocess(overwrite=False) data = data_class() logger.info(f"Preprocessing {data.__name__}") diff --git a/pyproject.toml b/pyproject.toml index d8c2135..dfd19c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,9 @@ classifiers = [ "Programming Language :: Python :: 3.11", ] +[project.scripts] +openqdc = "openqdc.cli:app" + [project.urls] Website = "https://github.com/OpenDrugDiscovery" "Source Code" = "https://github.com/OpenDrugDiscovery/openQDC" From 2a066371683ca9f7f7070cbb028383fe9e622de1 Mon Sep 17 00:00:00 2001 From: FNTwin Date: Thu, 29 Feb 2024 11:35:16 -0700 Subject: [PATCH 08/28] mkdocs dependency + fix --- env.yml | 1 + mkdocs.yml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/env.yml b/env.yml index 76d2c22..43c7df7 100644 --- a/env.yml +++ b/env.yml @@ -43,3 +43,4 @@ dependencies: - mkdocs-jupyter - markdown-include - mdx_truly_sane_lists + - mkdocstrings-python diff --git a/mkdocs.yml b/mkdocs.yml index e174b70..c1be218 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -58,13 +58,13 @@ plugins: - search - mkdocstrings: watch: - - src/ + - openqdc/ handlers: python: setup_commands: - import sys - sys.path.append("docs") - - sys.path.append("src") + - sys.path.append("openqdc") selection: new_path_syntax: yes rendering: From 5e179d0d18c03932055524987fd09378c7bda768 Mon Sep 17 00:00:00 2001 From: FNTwin Date: Thu, 29 Feb 2024 12:28:50 -0700 Subject: [PATCH 09/28] Tutorial update + mkdocs fix --- docs/tutorials/usage.ipynb | 774 ++++++++++++++++++++++++++++--------- env.yml | 1 + openqdc/cli.py | 5 +- 3 files changed, 594 insertions(+), 186 deletions(-) diff --git a/docs/tutorials/usage.ipynb b/docs/tutorials/usage.ipynb index b494396..cd71b6a 100644 --- a/docs/tutorials/usage.ipynb +++ b/docs/tutorials/usage.ipynb @@ -4,243 +4,267 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Really Hard example\n", + "# OpenQDC Hands On tutorial\n", "\n", "## Instantiate and GO!\n", "\n", - "If you don't have the dataset downloaded it will be downloaded automatically and cached. You just instantiate the class and you are ready to go." + "If you don't have the dataset downloaded it will be downloaded automatically and cached. You just instantiate the class and you are ready to go.\n", + "Change of units are done automatically on loading based on the units in the dataset." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/opt/homebrew/Caskroom/miniconda/base/envs/qdc/lib/python3.11/site-packages/google/auth/_default.py:76: UserWarning: Your application has authenticated using end user credentials from Google Cloud SDK without a quota project. You might receive a \"quota exceeded\" or \"API not enabled\" error. See the following page for troubleshooting: https://cloud.google.com/docs/authentication/adc-troubleshooting/user-creds. \n", - " warnings.warn(_CLOUD_SDK_CREDENTIALS_WARNING)\n", - "\u001b[32m2023-10-31 11:43:09.510\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mopenqdc.datasets.base\u001b[0m:\u001b[36mread_preprocess\u001b[0m:\u001b[36m236\u001b[0m - \u001b[1mReading preprocessed data\u001b[0m\n", - "\u001b[32m2023-10-31 11:43:09.511\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mopenqdc.datasets.base\u001b[0m:\u001b[36mread_preprocess\u001b[0m:\u001b[36m237\u001b[0m - \u001b[1mspice data with the following units:\n", + "\u001b[32m2024-02-29 12:17:13.349\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mopenqdc.datasets.base\u001b[0m:\u001b[36mread_preprocess\u001b[0m:\u001b[36m381\u001b[0m - \u001b[1mReading preprocessed data.\u001b[0m\n", + "\u001b[32m2024-02-29 12:17:13.349\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mopenqdc.datasets.base\u001b[0m:\u001b[36mread_preprocess\u001b[0m:\u001b[36m382\u001b[0m - \u001b[1mDataset spice with the following units:\n", " Energy: hartree,\n", " Distance: bohr,\n", - " Forces: hartree/bohr\u001b[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loaded atomic_inputs with shape (33175288, 5), dtype float32\n", - "Loaded position_idx_range with shape (1110165, 2), dtype int32\n", - "Loaded energies with shape (1110165, 1), dtype float32\n", - "Loaded forces with shape (33175288, 3, 1), dtype float32\n", - "Loaded name_uniques with shape (19155,), dtype " + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "plt.scatter(\n", " embedding[:, 0],\n", " embedding[:, 1],\n", - " c=[ds[i] for i in datum[\"indices\"]])\n", + " c=[(ds[i].energies - ds[i][\"e0\"].sum() )/ ds.data[\"n_atoms\"][i] for i in datum[\"idxs\"]])\n", "plt.colorbar()\n" ] } ], "metadata": { "kernelspec": { - "display_name": "qdc", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -416,7 +824,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.6" + "version": "3.12.2" } }, "nbformat": 4, diff --git a/env.yml b/env.yml index 43c7df7..53663c9 100644 --- a/env.yml +++ b/env.yml @@ -10,6 +10,7 @@ dependencies: - fsspec - gcsfs - typer + - prettytable # Scientific - pandas diff --git a/openqdc/cli.py b/openqdc/cli.py index 72a57a3..2a857d0 100644 --- a/openqdc/cli.py +++ b/openqdc/cli.py @@ -53,12 +53,11 @@ def datasets(): """ Print the available datasets. """ - table = PrettyTable(['Name', 'Level of theories', 'Has forces'], max_width=25) - table._max_width={} + table = PrettyTable(['Name', 'Forces', 'Level of theory']) for dataset in AVAILABLE_DATASETS: empty_dataset=AVAILABLE_DATASETS[dataset].no_init() has_forces = False if not empty_dataset.__force_methods__ else True - table.add_row([dataset, ",".join(empty_dataset.__energy_methods__),has_forces]) + table.add_row([dataset,has_forces, ",".join(empty_dataset.__energy_methods__)]) table.align="l" print(table) From caf4976d5bf1574dcc2808b582e32fff5ca3f653 Mon Sep 17 00:00:00 2001 From: FNTwin Date: Thu, 29 Feb 2024 12:35:29 -0700 Subject: [PATCH 10/28] Updated readme --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index c143e95..4c5097b 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,26 @@ You can run tests locally with: pytest ``` +### Documentation + +You can build the documentation locally with: + +```bash +mkdocs serve +``` + +# Downloading Datasets + +A command line interface is available to download datasets or see which dataset is available, please run openqdc --help. + +```bash +# Display the available datasets +openqdc datasets + +# Download the Spice and QMugs dataset +openqdc download --datasets Spice QMugs +``` + # Overview of Datasets