StructureCloud 0.0.1__tar.gz → 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- structurecloud-0.0.2/PKG-INFO +201 -0
- structurecloud-0.0.2/README.md +173 -0
- structurecloud-0.0.2/pyproject.toml +51 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/AlexMP20/alexmp20.py +103 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/GEOM/geom.py +176 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/LBA/lba.py +232 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/MD17/md17.py +105 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/MP20/mp20.py +107 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/MP20/mp20_dataset.py +122 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/PCQM4Mv2/PCQ.py +55 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/PCQM4Mv2/_PCQ.py +18 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/QM9/load_structure_cloud.py +85 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/QM9/qm9.py +133 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/QM9/structure_cloud_dataclass.py +161 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/SPICE/__init__.py +3 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/SPICE/spice.py +249 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/WBM/__init__.py +3 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/WBM/wbm.py +185 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/__init__.py +45 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/carbon_24/carbon24.py +102 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/collated.py +100 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/matbench/matbench.py +106 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/omol25/dataset.py +0 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/perov_5/perov5.py +107 -0
- {structurecloud-0.0.1 → structurecloud-0.0.2}/src/StructureCloud/Datasets/preprocess.py +183 -12
- structurecloud-0.0.2/src/StructureCloud/Datasets/retrieval.py +298 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/retrieval_torchgeometric.py +44 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/samplers.py +181 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/stacking.py +158 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/stats.py +191 -0
- structurecloud-0.0.2/src/StructureCloud/Datasets/utils.py +273 -0
- structurecloud-0.0.2/src/StructureCloud/chem_tools/__init__.py +6 -0
- structurecloud-0.0.2/src/StructureCloud/chem_tools/atom_properties.py +500 -0
- structurecloud-0.0.2/src/StructureCloud/chem_tools/bond_properties.py +347 -0
- structurecloud-0.0.2/src/StructureCloud/chem_tools/plot.py +339 -0
- structurecloud-0.0.2/src/StructureCloud/models/arch/ET/ET.py +183 -0
- structurecloud-0.0.2/src/StructureCloud/models/arch/ET/__init__.py +5 -0
- structurecloud-0.0.2/src/StructureCloud/models/arch/ET/equivariant_transformer.py +432 -0
- structurecloud-0.0.2/src/StructureCloud/models/arch/ET/extensions/__init__.py +160 -0
- structurecloud-0.0.2/src/StructureCloud/models/arch/ET/output_modules.py +328 -0
- structurecloud-0.0.2/src/StructureCloud/models/arch/ET/setup.py +80 -0
- structurecloud-0.0.2/src/StructureCloud/models/arch/ET/utils.py +872 -0
- structurecloud-0.0.2/src/StructureCloud/models/arch/__init__.py +1 -0
- structurecloud-0.0.2/src/StructureCloud/utils/__init__.py +1 -0
- structurecloud-0.0.2/src/StructureCloud/utils/augment.py +136 -0
- structurecloud-0.0.2/src/StructureCloud/utils/clipper.py +323 -0
- structurecloud-0.0.2/src/StructureCloud/utils/graph/__init__.py +0 -0
- structurecloud-0.0.2/src/StructureCloud/utils/graph/compute_graph.py +232 -0
- structurecloud-0.0.2/src/StructureCloud/utils/graph/radius_graph_pbc.py +733 -0
- structurecloud-0.0.2/src/StructureCloud/utils/view.py +1 -0
- structurecloud-0.0.2/src/StructureCloud.egg-info/PKG-INFO +201 -0
- structurecloud-0.0.2/src/StructureCloud.egg-info/SOURCES.txt +55 -0
- structurecloud-0.0.2/src/StructureCloud.egg-info/requires.txt +15 -0
- structurecloud-0.0.1/PKG-INFO +0 -101
- structurecloud-0.0.1/README.md +0 -86
- structurecloud-0.0.1/pyproject.toml +0 -24
- structurecloud-0.0.1/src/StructureCloud/Datasets/__init__.py +0 -1
- structurecloud-0.0.1/src/StructureCloud/Datasets/retrieval.py +0 -53
- structurecloud-0.0.1/src/StructureCloud.egg-info/PKG-INFO +0 -101
- structurecloud-0.0.1/src/StructureCloud.egg-info/SOURCES.txt +0 -10
- {structurecloud-0.0.1 → structurecloud-0.0.2}/LICENSE +0 -0
- {structurecloud-0.0.1 → structurecloud-0.0.2}/setup.cfg +0 -0
- {structurecloud-0.0.1 → structurecloud-0.0.2}/src/StructureCloud.egg-info/dependency_links.txt +0 -0
- {structurecloud-0.0.1 → structurecloud-0.0.2}/src/StructureCloud.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: StructureCloud
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Standard formating and easy access to 3D structural datasets for machine learning. currently under development...
|
|
5
|
+
Author-email: Ty Perez <ty.jperez@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/TyJPerez/StructureCloud
|
|
8
|
+
Project-URL: Issues, https://github.com/TyJPerez/StructureCloud/issues
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: torch
|
|
15
|
+
Requires-Dist: torch_geometric
|
|
16
|
+
Requires-Dist: huggingface_hub>=0.20
|
|
17
|
+
Requires-Dist: numpy>=1.21
|
|
18
|
+
Requires-Dist: tqdm>=4.60
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: matplotlib>=3.5; extra == "dev"
|
|
21
|
+
Requires-Dist: scipy>=1.7; extra == "dev"
|
|
22
|
+
Requires-Dist: rdkit>=2022.3; extra == "dev"
|
|
23
|
+
Requires-Dist: datasets>=2.0; extra == "dev"
|
|
24
|
+
Provides-Extra: viz
|
|
25
|
+
Requires-Dist: matplotlib>=3.5; extra == "viz"
|
|
26
|
+
Requires-Dist: plotly>=5.0; extra == "viz"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# StructureCloud
|
|
30
|
+
|
|
31
|
+
A collection of 3D atomistic (point-cloud) datasets for machine learning on molecules and
|
|
32
|
+
materials — property prediction, representation learning, and generative modeling. Every
|
|
33
|
+
dataset is exposed through a single, uniform loader that returns
|
|
34
|
+
[PyTorch Geometric](https://pytorch-geometric.readthedocs.io/) `Data` objects, and is stored
|
|
35
|
+
in a **memory-mapped, collated format** so that many large datasets can be **stacked and
|
|
36
|
+
trained on together without exhausting RAM**.
|
|
37
|
+
|
|
38
|
+
## Why StructureCloud
|
|
39
|
+
|
|
40
|
+
Atomistic datasets ship in many incompatible formats (jsonl, LMDB, parquet, per-source
|
|
41
|
+
schemas) and decoding them one row at a time is slow and RAM-hungry. StructureCloud solves
|
|
42
|
+
this with three conventions shared across every dataset:
|
|
43
|
+
|
|
44
|
+
- **One uniform sample schema.** Each item is a PyG `Data` with `pos` `[N,3]` (Å) and `z`
|
|
45
|
+
`[N]` (atomic numbers); periodic crystals add `cell` `[1,3,3]` and `pbc` `[1,3]`. Labels
|
|
46
|
+
carry short, descriptive keys — never a bare `y`/`dy`.
|
|
47
|
+
- **Collated + memory-mapped storage.** Each split is preprocessed once into a single
|
|
48
|
+
`.pt` file where *everything is a tensor* (variable-length atom arrays are concatenated
|
|
49
|
+
with offset tables; strings are packed). `torch.load(mmap=True)` pages tensors in from
|
|
50
|
+
disk through the shared OS page cache, so stacking N datasets costs the combined working
|
|
51
|
+
set, not the sum of their sizes.
|
|
52
|
+
- **Download-only loaders.** Preprocessed files live on the Hugging Face Hub under
|
|
53
|
+
`StructureCloud/{dataset}`; the loader downloads the split it needs and maps it — no
|
|
54
|
+
building from raw at load time.
|
|
55
|
+
|
|
56
|
+
## Install
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install StructureCloud
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or from source (editable), e.g. for development or to preprocess new datasets:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/TyJPerez/StructureCloud.git
|
|
66
|
+
cd StructureCloud
|
|
67
|
+
pip install -e .
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Dependencies.** The core install pulls in everything needed to load and stack datasets:
|
|
71
|
+
`torch`, `torch_geometric`, `huggingface_hub`, `numpy`, and `tqdm`. Split files download
|
|
72
|
+
automatically from the Hugging Face Hub on first use and are cached locally.
|
|
73
|
+
|
|
74
|
+
> **Install `torch` and `torch_geometric` first, matched to your platform.** Their wheels are
|
|
75
|
+
> tied to your CUDA/CPU setup, so they are intentionally left unpinned here — follow the
|
|
76
|
+
> official [PyTorch](https://pytorch.org/get-started/locally/) and
|
|
77
|
+
> [PyG](https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html)
|
|
78
|
+
> install instructions for your system, then install StructureCloud.
|
|
79
|
+
|
|
80
|
+
Two optional extras cover the tooling beyond loading:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install "StructureCloud[dev]" # preprocessing + figures/stats: matplotlib, scipy, rdkit, datasets
|
|
84
|
+
pip install "StructureCloud[viz]" # 3D structure/atom plotting in StructureCloud.chem_tools: matplotlib, plotly
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Quickstart
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from StructureCloud.Datasets import QM9
|
|
91
|
+
|
|
92
|
+
# Downloads and memory-maps StructureCloud/QM9 preprocessed 'train' split
|
|
93
|
+
ds = QM9(split='train') # pass mmap=False to load fully into RAM
|
|
94
|
+
print(len(ds)) # number of structures
|
|
95
|
+
|
|
96
|
+
data = ds[0] # a torch_geometric.data.Data
|
|
97
|
+
data.pos # [N, 3] float32 positions (Angstrom)
|
|
98
|
+
data.z # [N] int64 atomic numbers
|
|
99
|
+
data.smiles # str metadata
|
|
100
|
+
data.y # (19,) DFT property vector (QM9-specific)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Every loader takes the common arguments `split`, `transform`, `mmap`, and `root` (custom
|
|
104
|
+
cache location); dataset-specific arguments (`label`, `subset`, `components`, `sample`, …)
|
|
105
|
+
are documented in each loader's docstring and in that dataset's `README.md`. Batch with a
|
|
106
|
+
standard PyG `DataLoader`:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from torch_geometric.loader import DataLoader
|
|
110
|
+
loader = DataLoader(ds, batch_size=64, shuffle=True)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Available datasets
|
|
114
|
+
|
|
115
|
+
Import any of these from `StructureCloud.Datasets`.
|
|
116
|
+
|
|
117
|
+
### Small organic molecules (molecular, non-periodic)
|
|
118
|
+
|
|
119
|
+
| Dataset | Size | Description | Splits |
|
|
120
|
+
|---|---|---|---|
|
|
121
|
+
| `QM9` | 130,831 molecules | CHONF, ≤9 heavy atoms; relaxed geometry + 19 DFT properties | `train` |
|
|
122
|
+
| `PCQM4Mv2` (alias `PCQ`) | 3,378,550 molecules | DFT-relaxed geometry + HOMO–LUMO gap (OGB-LSC / PubChemQC) | `train` |
|
|
123
|
+
| `GEOM` | ~37M conformers / ~450k molecules | Conformer **ensemble** (energies + Boltzmann weights); variants `GEOM`/`GEOM64`/`GEOM32`/`GEOM10`/`GEOM1`, collections `drugs`/`qm9`/`molnet` | per-collection |
|
|
124
|
+
| `SPICE1` / `SPICE2` | 19,238 mol / 1.11M conf · 113,985 mol / 2.0M conf | QC single-points with per-atom **forces** + per-conformer energies (ωB97M-D3(BJ)/def2-TZVPPD); conformer ensemble | `all` |
|
|
125
|
+
| `MD17` | 10 molecules × ~100k frames | rMD17 MD trajectories; energy + forces at PBE/def2-SVP; each molecule is its own split | per-molecule |
|
|
126
|
+
|
|
127
|
+
### Materials (periodic crystals)
|
|
128
|
+
|
|
129
|
+
| Dataset | Size | Description | Splits |
|
|
130
|
+
|---|---|---|---|
|
|
131
|
+
| `MP20` | 45,229 crystals | ≤20-atom Materials Project crystals; standard generation benchmark | `train`/`val`/`test` |
|
|
132
|
+
| `AlexMP20` | 675,204 crystals | ≤20-atom crystals from Alexandria + MP; stability, band gap, elastic/magnetic properties | `train`/`val`/`test`/`all` |
|
|
133
|
+
| `Carbon24` | 10,153 crystals | Carbon-only crystals from ab-initio random structure search; energy/atom label | `train`/`val`/`test` |
|
|
134
|
+
| `Perov5` | 18,928 crystals | Perovskite ABX₃, fixed 5-atom cell; formation energy + band gap | `train`/`val`/`test` |
|
|
135
|
+
| `WBM` | 256,963 crystals | Matbench Discovery test set; unrelaxed→relaxed formation energy / stability (85 elements) | `test` |
|
|
136
|
+
| `Matbench` | 9 tasks | The 9 structure-based Matbench property tasks; fixed 5-fold CV (`mp_gap`, `mp_e_form`, `perovskites`, `phonons`, `dielectric`, `jdft2d`, `log_gvrh`, `log_kvrh`, `mp_is_metal`) | per-task |
|
|
137
|
+
|
|
138
|
+
### Proteins and biomolecules
|
|
139
|
+
|
|
140
|
+
| Dataset | Size | Description | Splits |
|
|
141
|
+
|---|---|---|---|
|
|
142
|
+
| `LBA` | 4,463 complexes | Protein–ligand binding affinity (Atom3D / PDBbind); full protein preserved, available as `protein`/`pocket`/`ligand` components | `train`/`val`/`test`/`all` |
|
|
143
|
+
|
|
144
|
+
## Stacking datasets
|
|
145
|
+
|
|
146
|
+
The core feature: concatenate arbitrary datasets into one memory-mapped training set with a
|
|
147
|
+
uniform key schema. `StackedDataset` tags each sample's origin (`AddTag`) and standardizes
|
|
148
|
+
keys (`StandardizeKeys` fills a `cell` bounding box / `pbc` for molecular samples and a
|
|
149
|
+
unified `str_id`), so a mixed molecular + periodic batch collates through a single PyG
|
|
150
|
+
`DataLoader`.
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
from StructureCloud.Datasets import AlexMP20, GEOM, PCQM4Mv2, StackedDataset
|
|
154
|
+
|
|
155
|
+
stk = StackedDataset(
|
|
156
|
+
[AlexMP20('all', label=None), GEOM('GEOM10', 'drugs'), PCQM4Mv2()],
|
|
157
|
+
tags=['alexmp20', 'geom10', 'pcq'],
|
|
158
|
+
keep_keys=['pos', 'z', 'cell', 'pbc', 'natoms', 'str_id', 'tag'],
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Because every dataset is memory-mapped, a stack that is several GB on disk stays at a small
|
|
163
|
+
resident footprint, with cold pages evicted under memory pressure and shared across
|
|
164
|
+
DataLoader workers.
|
|
165
|
+
|
|
166
|
+
## Conformer-ensemble datasets
|
|
167
|
+
|
|
168
|
+
`GEOM` and `SPICE` carry many conformers per molecule. Their loaders return one conformer
|
|
169
|
+
per access with selectable sampling: `sample=True` (random conformer, default),
|
|
170
|
+
`sample=False` (flatten — index every molecule/conformer pair), or `sample_fn=…` with a
|
|
171
|
+
shared sampler from `StructureCloud.Datasets.samplers` (`sample_by_relative`,
|
|
172
|
+
`sample_by_boltzmann`).
|
|
173
|
+
|
|
174
|
+
## Roadmap
|
|
175
|
+
|
|
176
|
+
- **OMol25** (Meta FAIR Open Molecules 2025) — large molecular DFT single-point dataset
|
|
177
|
+
(energy + forces + variable charge/spin at ωB97M-V/def2-TZVPD). *In progress.*
|
|
178
|
+
- **QMOF** — periodic metal–organic-framework DFT properties (~20,372 MOFs; band gaps,
|
|
179
|
+
per-atom charges/magmoms, pore descriptors). *Planned.*
|
|
180
|
+
- **3D objects** and **Gaussian splats** — planned.
|
|
181
|
+
|
|
182
|
+
## Also in this repo
|
|
183
|
+
|
|
184
|
+
Beyond the datasets, the package includes early/experimental modules that are not the focus
|
|
185
|
+
of this README: `StructureCloud.models` (an equivariant-transformer architecture),
|
|
186
|
+
`StructureCloud.utils` (graph construction, augmentation, structure viewing), and
|
|
187
|
+
`StructureCloud.chem_tools` (3D atom/material plotting, atomic properties).
|
|
188
|
+
|
|
189
|
+
## Contributing a dataset
|
|
190
|
+
|
|
191
|
+
Dataset conventions, the collated/memory-mapped format, and the step-by-step process for
|
|
192
|
+
adding a new dataset are documented under `.agents/docs/` — start with
|
|
193
|
+
[`about.md`](.agents/docs/about.md) and
|
|
194
|
+
[`adding_dataset/guidelines.md`](.agents/docs/adding_dataset/guidelines.md). New loaders
|
|
195
|
+
subclass `CollatedStructureDataset` (`Datasets/collated.py`), ship a `README.md`, a
|
|
196
|
+
distribution figure, and a `stats.json`, and register in `Datasets/__init__.py` and the
|
|
197
|
+
verification harness (`scripts/verify_dataset.py`).
|
|
198
|
+
|
|
199
|
+
## License
|
|
200
|
+
|
|
201
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# StructureCloud
|
|
2
|
+
|
|
3
|
+
A collection of 3D atomistic (point-cloud) datasets for machine learning on molecules and
|
|
4
|
+
materials — property prediction, representation learning, and generative modeling. Every
|
|
5
|
+
dataset is exposed through a single, uniform loader that returns
|
|
6
|
+
[PyTorch Geometric](https://pytorch-geometric.readthedocs.io/) `Data` objects, and is stored
|
|
7
|
+
in a **memory-mapped, collated format** so that many large datasets can be **stacked and
|
|
8
|
+
trained on together without exhausting RAM**.
|
|
9
|
+
|
|
10
|
+
## Why StructureCloud
|
|
11
|
+
|
|
12
|
+
Atomistic datasets ship in many incompatible formats (jsonl, LMDB, parquet, per-source
|
|
13
|
+
schemas) and decoding them one row at a time is slow and RAM-hungry. StructureCloud solves
|
|
14
|
+
this with three conventions shared across every dataset:
|
|
15
|
+
|
|
16
|
+
- **One uniform sample schema.** Each item is a PyG `Data` with `pos` `[N,3]` (Å) and `z`
|
|
17
|
+
`[N]` (atomic numbers); periodic crystals add `cell` `[1,3,3]` and `pbc` `[1,3]`. Labels
|
|
18
|
+
carry short, descriptive keys — never a bare `y`/`dy`.
|
|
19
|
+
- **Collated + memory-mapped storage.** Each split is preprocessed once into a single
|
|
20
|
+
`.pt` file where *everything is a tensor* (variable-length atom arrays are concatenated
|
|
21
|
+
with offset tables; strings are packed). `torch.load(mmap=True)` pages tensors in from
|
|
22
|
+
disk through the shared OS page cache, so stacking N datasets costs the combined working
|
|
23
|
+
set, not the sum of their sizes.
|
|
24
|
+
- **Download-only loaders.** Preprocessed files live on the Hugging Face Hub under
|
|
25
|
+
`StructureCloud/{dataset}`; the loader downloads the split it needs and maps it — no
|
|
26
|
+
building from raw at load time.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install StructureCloud
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or from source (editable), e.g. for development or to preprocess new datasets:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/TyJPerez/StructureCloud.git
|
|
38
|
+
cd StructureCloud
|
|
39
|
+
pip install -e .
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Dependencies.** The core install pulls in everything needed to load and stack datasets:
|
|
43
|
+
`torch`, `torch_geometric`, `huggingface_hub`, `numpy`, and `tqdm`. Split files download
|
|
44
|
+
automatically from the Hugging Face Hub on first use and are cached locally.
|
|
45
|
+
|
|
46
|
+
> **Install `torch` and `torch_geometric` first, matched to your platform.** Their wheels are
|
|
47
|
+
> tied to your CUDA/CPU setup, so they are intentionally left unpinned here — follow the
|
|
48
|
+
> official [PyTorch](https://pytorch.org/get-started/locally/) and
|
|
49
|
+
> [PyG](https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html)
|
|
50
|
+
> install instructions for your system, then install StructureCloud.
|
|
51
|
+
|
|
52
|
+
Two optional extras cover the tooling beyond loading:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install "StructureCloud[dev]" # preprocessing + figures/stats: matplotlib, scipy, rdkit, datasets
|
|
56
|
+
pip install "StructureCloud[viz]" # 3D structure/atom plotting in StructureCloud.chem_tools: matplotlib, plotly
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Quickstart
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from StructureCloud.Datasets import QM9
|
|
63
|
+
|
|
64
|
+
# Downloads and memory-maps StructureCloud/QM9 preprocessed 'train' split
|
|
65
|
+
ds = QM9(split='train') # pass mmap=False to load fully into RAM
|
|
66
|
+
print(len(ds)) # number of structures
|
|
67
|
+
|
|
68
|
+
data = ds[0] # a torch_geometric.data.Data
|
|
69
|
+
data.pos # [N, 3] float32 positions (Angstrom)
|
|
70
|
+
data.z # [N] int64 atomic numbers
|
|
71
|
+
data.smiles # str metadata
|
|
72
|
+
data.y # (19,) DFT property vector (QM9-specific)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Every loader takes the common arguments `split`, `transform`, `mmap`, and `root` (custom
|
|
76
|
+
cache location); dataset-specific arguments (`label`, `subset`, `components`, `sample`, …)
|
|
77
|
+
are documented in each loader's docstring and in that dataset's `README.md`. Batch with a
|
|
78
|
+
standard PyG `DataLoader`:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from torch_geometric.loader import DataLoader
|
|
82
|
+
loader = DataLoader(ds, batch_size=64, shuffle=True)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Available datasets
|
|
86
|
+
|
|
87
|
+
Import any of these from `StructureCloud.Datasets`.
|
|
88
|
+
|
|
89
|
+
### Small organic molecules (molecular, non-periodic)
|
|
90
|
+
|
|
91
|
+
| Dataset | Size | Description | Splits |
|
|
92
|
+
|---|---|---|---|
|
|
93
|
+
| `QM9` | 130,831 molecules | CHONF, ≤9 heavy atoms; relaxed geometry + 19 DFT properties | `train` |
|
|
94
|
+
| `PCQM4Mv2` (alias `PCQ`) | 3,378,550 molecules | DFT-relaxed geometry + HOMO–LUMO gap (OGB-LSC / PubChemQC) | `train` |
|
|
95
|
+
| `GEOM` | ~37M conformers / ~450k molecules | Conformer **ensemble** (energies + Boltzmann weights); variants `GEOM`/`GEOM64`/`GEOM32`/`GEOM10`/`GEOM1`, collections `drugs`/`qm9`/`molnet` | per-collection |
|
|
96
|
+
| `SPICE1` / `SPICE2` | 19,238 mol / 1.11M conf · 113,985 mol / 2.0M conf | QC single-points with per-atom **forces** + per-conformer energies (ωB97M-D3(BJ)/def2-TZVPPD); conformer ensemble | `all` |
|
|
97
|
+
| `MD17` | 10 molecules × ~100k frames | rMD17 MD trajectories; energy + forces at PBE/def2-SVP; each molecule is its own split | per-molecule |
|
|
98
|
+
|
|
99
|
+
### Materials (periodic crystals)
|
|
100
|
+
|
|
101
|
+
| Dataset | Size | Description | Splits |
|
|
102
|
+
|---|---|---|---|
|
|
103
|
+
| `MP20` | 45,229 crystals | ≤20-atom Materials Project crystals; standard generation benchmark | `train`/`val`/`test` |
|
|
104
|
+
| `AlexMP20` | 675,204 crystals | ≤20-atom crystals from Alexandria + MP; stability, band gap, elastic/magnetic properties | `train`/`val`/`test`/`all` |
|
|
105
|
+
| `Carbon24` | 10,153 crystals | Carbon-only crystals from ab-initio random structure search; energy/atom label | `train`/`val`/`test` |
|
|
106
|
+
| `Perov5` | 18,928 crystals | Perovskite ABX₃, fixed 5-atom cell; formation energy + band gap | `train`/`val`/`test` |
|
|
107
|
+
| `WBM` | 256,963 crystals | Matbench Discovery test set; unrelaxed→relaxed formation energy / stability (85 elements) | `test` |
|
|
108
|
+
| `Matbench` | 9 tasks | The 9 structure-based Matbench property tasks; fixed 5-fold CV (`mp_gap`, `mp_e_form`, `perovskites`, `phonons`, `dielectric`, `jdft2d`, `log_gvrh`, `log_kvrh`, `mp_is_metal`) | per-task |
|
|
109
|
+
|
|
110
|
+
### Proteins and biomolecules
|
|
111
|
+
|
|
112
|
+
| Dataset | Size | Description | Splits |
|
|
113
|
+
|---|---|---|---|
|
|
114
|
+
| `LBA` | 4,463 complexes | Protein–ligand binding affinity (Atom3D / PDBbind); full protein preserved, available as `protein`/`pocket`/`ligand` components | `train`/`val`/`test`/`all` |
|
|
115
|
+
|
|
116
|
+
## Stacking datasets
|
|
117
|
+
|
|
118
|
+
The core feature: concatenate arbitrary datasets into one memory-mapped training set with a
|
|
119
|
+
uniform key schema. `StackedDataset` tags each sample's origin (`AddTag`) and standardizes
|
|
120
|
+
keys (`StandardizeKeys` fills a `cell` bounding box / `pbc` for molecular samples and a
|
|
121
|
+
unified `str_id`), so a mixed molecular + periodic batch collates through a single PyG
|
|
122
|
+
`DataLoader`.
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from StructureCloud.Datasets import AlexMP20, GEOM, PCQM4Mv2, StackedDataset
|
|
126
|
+
|
|
127
|
+
stk = StackedDataset(
|
|
128
|
+
[AlexMP20('all', label=None), GEOM('GEOM10', 'drugs'), PCQM4Mv2()],
|
|
129
|
+
tags=['alexmp20', 'geom10', 'pcq'],
|
|
130
|
+
keep_keys=['pos', 'z', 'cell', 'pbc', 'natoms', 'str_id', 'tag'],
|
|
131
|
+
)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Because every dataset is memory-mapped, a stack that is several GB on disk stays at a small
|
|
135
|
+
resident footprint, with cold pages evicted under memory pressure and shared across
|
|
136
|
+
DataLoader workers.
|
|
137
|
+
|
|
138
|
+
## Conformer-ensemble datasets
|
|
139
|
+
|
|
140
|
+
`GEOM` and `SPICE` carry many conformers per molecule. Their loaders return one conformer
|
|
141
|
+
per access with selectable sampling: `sample=True` (random conformer, default),
|
|
142
|
+
`sample=False` (flatten — index every molecule/conformer pair), or `sample_fn=…` with a
|
|
143
|
+
shared sampler from `StructureCloud.Datasets.samplers` (`sample_by_relative`,
|
|
144
|
+
`sample_by_boltzmann`).
|
|
145
|
+
|
|
146
|
+
## Roadmap
|
|
147
|
+
|
|
148
|
+
- **OMol25** (Meta FAIR Open Molecules 2025) — large molecular DFT single-point dataset
|
|
149
|
+
(energy + forces + variable charge/spin at ωB97M-V/def2-TZVPD). *In progress.*
|
|
150
|
+
- **QMOF** — periodic metal–organic-framework DFT properties (~20,372 MOFs; band gaps,
|
|
151
|
+
per-atom charges/magmoms, pore descriptors). *Planned.*
|
|
152
|
+
- **3D objects** and **Gaussian splats** — planned.
|
|
153
|
+
|
|
154
|
+
## Also in this repo
|
|
155
|
+
|
|
156
|
+
Beyond the datasets, the package includes early/experimental modules that are not the focus
|
|
157
|
+
of this README: `StructureCloud.models` (an equivariant-transformer architecture),
|
|
158
|
+
`StructureCloud.utils` (graph construction, augmentation, structure viewing), and
|
|
159
|
+
`StructureCloud.chem_tools` (3D atom/material plotting, atomic properties).
|
|
160
|
+
|
|
161
|
+
## Contributing a dataset
|
|
162
|
+
|
|
163
|
+
Dataset conventions, the collated/memory-mapped format, and the step-by-step process for
|
|
164
|
+
adding a new dataset are documented under `.agents/docs/` — start with
|
|
165
|
+
[`about.md`](.agents/docs/about.md) and
|
|
166
|
+
[`adding_dataset/guidelines.md`](.agents/docs/adding_dataset/guidelines.md). New loaders
|
|
167
|
+
subclass `CollatedStructureDataset` (`Datasets/collated.py`), ship a `README.md`, a
|
|
168
|
+
distribution figure, and a `stats.json`, and register in `Datasets/__init__.py` and the
|
|
169
|
+
verification harness (`scripts/verify_dataset.py`).
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "StructureCloud" # must be unique on PyPI!
|
|
3
|
+
version = "0.0.2"
|
|
4
|
+
authors = [
|
|
5
|
+
{ name="Ty Perez", email="ty.jperez@gmail.com" },
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
description = "Standard formating and easy access to 3D structural datasets for machine learning. currently under development..."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Programming Language :: Python :: 3",
|
|
13
|
+
"Operating System :: OS Independent",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
license = "MIT"
|
|
17
|
+
license-files = ["LICEN[CS]E*"]
|
|
18
|
+
|
|
19
|
+
# Core runtime dependencies: everything needed to load and stack datasets.
|
|
20
|
+
# torch and torch_geometric are left unpinned on purpose: their wheels are
|
|
21
|
+
# CUDA/platform-specific and users normally install them for their own system
|
|
22
|
+
# first (see the README). Everything else gets a conservative lower-bound floor
|
|
23
|
+
# (no upper caps) so the package coexists with a user's existing environment.
|
|
24
|
+
dependencies = [
|
|
25
|
+
"torch",
|
|
26
|
+
"torch_geometric",
|
|
27
|
+
"huggingface_hub>=0.20",
|
|
28
|
+
"numpy>=1.21",
|
|
29
|
+
"tqdm>=4.60",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
# Preprocessing new datasets and generating distribution figures / stats.json.
|
|
34
|
+
dev = [
|
|
35
|
+
"matplotlib>=3.5",
|
|
36
|
+
"scipy>=1.7",
|
|
37
|
+
"rdkit>=2022.3",
|
|
38
|
+
"datasets>=2.0",
|
|
39
|
+
]
|
|
40
|
+
# 3D structure/atom plotting helpers in StructureCloud.chem_tools.
|
|
41
|
+
viz = [
|
|
42
|
+
"matplotlib>=3.5",
|
|
43
|
+
"plotly>=5.0",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[project.urls]
|
|
47
|
+
Homepage = "https://github.com/TyJPerez/StructureCloud"
|
|
48
|
+
Issues = "https://github.com/TyJPerez/StructureCloud/issues"
|
|
49
|
+
|
|
50
|
+
[tool.setuptools.packages.find]
|
|
51
|
+
where = ["src"] # <- Important to tell setuptools to find code inside src/
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from typing import Callable, Optional
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import torch
|
|
5
|
+
from torch.utils.data import ConcatDataset
|
|
6
|
+
from torch_geometric.data import Data
|
|
7
|
+
|
|
8
|
+
from ..collated import CollatedStructureDataset
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AlexMP20(CollatedStructureDataset):
|
|
12
|
+
'''Fast, memory-mapped loader for the preprocessed Alex-MP-20 dataset.
|
|
13
|
+
|
|
14
|
+
Downloads a collated ``.pt`` per split from ``StructureCloud/AlexMP20`` and
|
|
15
|
+
memory-maps it (see ``CollatedStructureDataset``); pass ``mmap=False`` to load
|
|
16
|
+
fully into RAM.
|
|
17
|
+
|
|
18
|
+
args:
|
|
19
|
+
split : one of ['train', 'val', 'test', 'all'] ('all' concatenates the three)
|
|
20
|
+
label : target label, one of ``all_labels`` (or None for no target)
|
|
21
|
+
transform : optional callable applied to each Data object
|
|
22
|
+
mmap : memory-map the collated file (default True)
|
|
23
|
+
'''
|
|
24
|
+
|
|
25
|
+
# available labels and their keys in the collated dataset
|
|
26
|
+
all_labels = {
|
|
27
|
+
'space_group': 'space_group',
|
|
28
|
+
'chemical_system': 'chemical_system',
|
|
29
|
+
'energy_above_hull': 'energy_above_hull',
|
|
30
|
+
'band_gap': 'dft_band_gap',
|
|
31
|
+
'bulk_modulus': 'dft_bulk_modulus',
|
|
32
|
+
'mag_density': 'dft_mag_density',
|
|
33
|
+
'hhi_score': 'hhi_score',
|
|
34
|
+
'ml_bulk_modulus': 'ml_bulk_modulus',
|
|
35
|
+
'id': 'ids',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
hf_repo = 'StructureCloud/AlexMP20'
|
|
39
|
+
available_splits = ['train', 'val', 'test', 'all']
|
|
40
|
+
string_fields = ('ids', 'space_group', 'chemical_system')
|
|
41
|
+
|
|
42
|
+
def __init__(self,
|
|
43
|
+
split: str = 'train',
|
|
44
|
+
label: Optional[str] = 'band_gap',
|
|
45
|
+
transform: Optional[Callable] = None,
|
|
46
|
+
mmap: bool = True,
|
|
47
|
+
root: Optional[str] = None,
|
|
48
|
+
):
|
|
49
|
+
assert split in self.available_splits, (
|
|
50
|
+
f"Split {split} not recognized. Available splits: {self.available_splits}"
|
|
51
|
+
)
|
|
52
|
+
if label is not None:
|
|
53
|
+
assert label in self.all_labels, (
|
|
54
|
+
f"Label {label} not recognized. Available labels: {list(self.all_labels)}"
|
|
55
|
+
)
|
|
56
|
+
self.label = label
|
|
57
|
+
|
|
58
|
+
if split == 'all':
|
|
59
|
+
# concatenate the three splits, each individually memory-mapped
|
|
60
|
+
self.split = 'all'
|
|
61
|
+
self.transform = transform
|
|
62
|
+
self._parts = [
|
|
63
|
+
AlexMP20(s, label=label, transform=None, mmap=mmap, root=root)
|
|
64
|
+
for s in ['train', 'val', 'test']
|
|
65
|
+
]
|
|
66
|
+
self._concat = ConcatDataset(self._parts)
|
|
67
|
+
self.num_structures = len(self._concat)
|
|
68
|
+
self.dataset = None
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
super().__init__(split, transform=transform, mmap=mmap, root=root)
|
|
72
|
+
|
|
73
|
+
def _label_value(self, idx):
|
|
74
|
+
key = self.all_labels[self.label]
|
|
75
|
+
if key in self.string_fields:
|
|
76
|
+
return self.decode(key, idx)
|
|
77
|
+
return self.dataset[key][idx].clone()
|
|
78
|
+
|
|
79
|
+
def __getitem__(self, idx):
|
|
80
|
+
if isinstance(idx, torch.Tensor):
|
|
81
|
+
idx = idx.item()
|
|
82
|
+
idx = int(idx)
|
|
83
|
+
|
|
84
|
+
if self.split == 'all':
|
|
85
|
+
data = self._concat[idx] # parts carry no transform
|
|
86
|
+
if self.transform is not None:
|
|
87
|
+
data = self.transform(data)
|
|
88
|
+
return data
|
|
89
|
+
|
|
90
|
+
out_data = Data()
|
|
91
|
+
out_data.pos = self.slice_by_ptr('pos', idx)
|
|
92
|
+
out_data.cell = self.dataset['cell'][idx].reshape(1, 3, 3).clone()
|
|
93
|
+
out_data.z = self.slice_by_ptr('z', idx)
|
|
94
|
+
out_data.pbc = self.dataset['pbc'][idx].reshape(1, 3).clone()
|
|
95
|
+
|
|
96
|
+
out_data.id = self.decode('ids', idx)
|
|
97
|
+
if self.label is not None:
|
|
98
|
+
out_data.y = self._label_value(idx)
|
|
99
|
+
|
|
100
|
+
if self.transform is not None:
|
|
101
|
+
out_data = self.transform(out_data)
|
|
102
|
+
|
|
103
|
+
return out_data
|