alignn 2026.8.6__py3-none-any.whl

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.
Files changed (79) hide show
  1. alignn/__init__.py +3 -0
  2. alignn/cli.py +73 -0
  3. alignn/config.py +253 -0
  4. alignn/data.py +578 -0
  5. alignn/dataset.py +180 -0
  6. alignn/ff/__init__.py +1 -0
  7. alignn/ff/all_models_alignn.json +59 -0
  8. alignn/ff/all_models_alignn_atomwise.json +58 -0
  9. alignn/ff/calculators.py +572 -0
  10. alignn/ff/ff.py +1574 -0
  11. alignn/ff/lammps_bridge.py +175 -0
  12. alignn/ff/unified_calculator.py +274 -0
  13. alignn/graphs.py +1353 -0
  14. alignn/lmdb_dataset.py +316 -0
  15. alignn/md/__init__.py +13 -0
  16. alignn/md/forces.py +79 -0
  17. alignn/md/integrators.py +382 -0
  18. alignn/md/relax.py +104 -0
  19. alignn/models/__init__.py +7 -0
  20. alignn/models/alignn.py +357 -0
  21. alignn/models/alignn_atomwise.py +701 -0
  22. alignn/models/alignn_atomwise_pure.py +909 -0
  23. alignn/models/alignn_atomwise_pure_smooth.py +717 -0
  24. alignn/models/ealignn_atomwise.py +452 -0
  25. alignn/models/model_zoo.py +246 -0
  26. alignn/models/utils.py +407 -0
  27. alignn/pretrained.py +672 -0
  28. alignn/pretrained2.py +1464 -0
  29. alignn/profiler.py +83 -0
  30. alignn/pure_lmdb_dataset.py +366 -0
  31. alignn/run_alignn_ff.py +257 -0
  32. alignn/scripts/__init__.py +1 -0
  33. alignn/scripts/alignn_evac.py +137 -0
  34. alignn/scripts/all_train_cgcnn.py +73 -0
  35. alignn/scripts/bench_dgl_vs_pure.py +345 -0
  36. alignn/scripts/compare_cfid.py +134 -0
  37. alignn/scripts/cubic_mat_relax.py +55 -0
  38. alignn/scripts/defect.py +74 -0
  39. alignn/scripts/early_stopping_checker.py +50 -0
  40. alignn/scripts/ev_curve.py +212 -0
  41. alignn/scripts/ev_curve_comp.py +64 -0
  42. alignn/scripts/export_torchscript.py +214 -0
  43. alignn/scripts/final_model.py +58 -0
  44. alignn/scripts/graph_viz.py +13 -0
  45. alignn/scripts/make_test_split_cross_pred.py +75 -0
  46. alignn/scripts/parity_dgl_vs_pure.py +229 -0
  47. alignn/scripts/plot_ff_results.py +163 -0
  48. alignn/scripts/plot_phonons_ff.py +61 -0
  49. alignn/scripts/predict.py +52 -0
  50. alignn/scripts/predict_db.py +83 -0
  51. alignn/scripts/predict_db_all.py +111 -0
  52. alignn/scripts/train_all_hmof.py +49 -0
  53. alignn/scripts/train_all_hpov.py +49 -0
  54. alignn/scripts/train_all_jv.py +71 -0
  55. alignn/scripts/train_all_jv_class.py +70 -0
  56. alignn/scripts/train_all_jv_dal.py +72 -0
  57. alignn/scripts/train_all_mp.py +50 -0
  58. alignn/scripts/train_all_oqmd.py +51 -0
  59. alignn/scripts/train_all_pdbbind.py +44 -0
  60. alignn/scripts/train_all_qetb.py +52 -0
  61. alignn/scripts/train_all_qm9_jctc.py +56 -0
  62. alignn/scripts/train_all_qmof.py +51 -0
  63. alignn/scripts/train_cgcnn_repo.py +66 -0
  64. alignn/scripts/train_edos_pdos.py +44 -0
  65. alignn/scripts/train_megnet.py +150 -0
  66. alignn/torch_graph_builder.py +689 -0
  67. alignn/train.py +934 -0
  68. alignn/train_alignn.py +573 -0
  69. alignn/train_props.py +181 -0
  70. alignn/utils.py +196 -0
  71. alignn-2026.8.6.data/scripts/export_torchscript.py +98 -0
  72. alignn-2026.8.6.data/scripts/pretrained.py +672 -0
  73. alignn-2026.8.6.data/scripts/run_alignn_ff.py +257 -0
  74. alignn-2026.8.6.data/scripts/train_alignn.py +573 -0
  75. alignn-2026.8.6.dist-info/METADATA +482 -0
  76. alignn-2026.8.6.dist-info/RECORD +79 -0
  77. alignn-2026.8.6.dist-info/WHEEL +6 -0
  78. alignn-2026.8.6.dist-info/licenses/LICENSE.rst +32 -0
  79. alignn-2026.8.6.dist-info/top_level.txt +1 -0
alignn/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """Version number."""
2
+
3
+ __version__ = "2026.8.6"
alignn/cli.py ADDED
@@ -0,0 +1,73 @@
1
+ """Ignite training cli."""
2
+
3
+ import json
4
+ import os
5
+ import shutil
6
+ from pathlib import Path
7
+
8
+ # from typing import Any, Dict, Optional, Union
9
+ from typing import Optional
10
+
11
+ import torch
12
+ import typer
13
+
14
+ from alignn.config import TrainingConfig
15
+ from alignn.profiler import profile_dgl
16
+ from alignn.train import train_dgl
17
+
18
+
19
+ def cli(
20
+ config: Optional[Path] = typer.Argument(None),
21
+ progress: bool = False,
22
+ checkpoint_dir: Path = Path("/tmp/models"),
23
+ store_outputs: bool = False,
24
+ tensorboard: bool = False,
25
+ profile: bool = False,
26
+ ):
27
+ """ALIGNN training cli.
28
+
29
+ config: path to json config file (conform to TrainingConfig)
30
+ progress: enable tqdm console logging
31
+ tensorboard: enable tensorboard logging
32
+ profile: run profiling script for one epoch instead of training
33
+ """
34
+ model_dir = config.parent
35
+
36
+ if config is None:
37
+ model_dir = os.getcwd()
38
+ config = TrainingConfig(epochs=10, n_train=32, n_val=32, batch_size=16)
39
+
40
+ elif config.is_file():
41
+ model_dir = config.parent
42
+ with open(config, "r") as f:
43
+ config = json.load(f)
44
+ config = TrainingConfig(**config)
45
+
46
+ if profile:
47
+ profile_dgl(config)
48
+ return
49
+
50
+ hist = train_dgl(
51
+ config,
52
+ progress=progress,
53
+ checkpoint_dir=checkpoint_dir,
54
+ store_outputs=store_outputs,
55
+ log_tensorboard=tensorboard,
56
+ )
57
+
58
+ # print(model_dir)
59
+ # with open(model_dir / "metrics.json", "w") as f:
60
+ # json.dump(hist, f)
61
+
62
+ torch.save(hist, model_dir / "metrics.pt")
63
+
64
+ with open(model_dir / "fullconfig.json", "w") as f:
65
+ json.dump(json.loads(config.json()), f, indent=2)
66
+
67
+ # move temporary checkpoint data into model_dir
68
+ for checkpoint in checkpoint_dir.glob("*.pt"):
69
+ shutil.copy(checkpoint, model_dir / checkpoint.name)
70
+
71
+
72
+ if __name__ == "__main__":
73
+ typer.run(cli)
alignn/config.py ADDED
@@ -0,0 +1,253 @@
1
+ """Pydantic model for default configuration and validation."""
2
+
3
+ import subprocess
4
+ from typing import Optional, Union
5
+ import os
6
+ from typing import Literal
7
+ from alignn.utils import BaseSettings
8
+ from alignn.models.alignn import ALIGNNConfig
9
+ from alignn.models.alignn_atomwise import ALIGNNAtomWiseConfig
10
+ from alignn.models.alignn_atomwise_pure import ALIGNNAtomWisePureConfig
11
+ from alignn.models.alignn_atomwise_pure_smooth import (
12
+ ALIGNNAtomWisePureSmoothConfig,
13
+ )
14
+ from alignn.models.ealignn_atomwise import eALIGNNAtomWiseConfig
15
+
16
+ # import torch
17
+
18
+ try:
19
+ VERSION = (
20
+ subprocess.check_output(["git", "rev-parse", "HEAD"]).decode().strip()
21
+ )
22
+ except Exception:
23
+ VERSION = "NA"
24
+ pass
25
+
26
+
27
+ FEATURESET_SIZE = {"basic": 11, "atomic_number": 1, "cfid": 438, "cgcnn": 92}
28
+
29
+
30
+ TARGET_ENUM = Literal[
31
+ "formation_energy_peratom",
32
+ "optb88vdw_bandgap",
33
+ "bulk_modulus_kv",
34
+ "shear_modulus_gv",
35
+ "mbj_bandgap",
36
+ "slme",
37
+ "magmom_oszicar",
38
+ "spillage",
39
+ "kpoint_length_unit",
40
+ "encut",
41
+ "optb88vdw_total_energy",
42
+ "epsx",
43
+ "epsy",
44
+ "epsz",
45
+ "mepsx",
46
+ "mepsy",
47
+ "mepsz",
48
+ "max_ir_mode",
49
+ "min_ir_mode",
50
+ "n-Seebeck",
51
+ "p-Seebeck",
52
+ "n-powerfact",
53
+ "p-powerfact",
54
+ "ncond",
55
+ "pcond",
56
+ "nkappa",
57
+ "pkappa",
58
+ "ehull",
59
+ "exfoliation_energy",
60
+ "dfpt_piezo_max_dielectric",
61
+ "dfpt_piezo_max_eij",
62
+ "dfpt_piezo_max_dij",
63
+ "gap pbe",
64
+ "e_form",
65
+ "e_hull",
66
+ "energy_per_atom",
67
+ "formation_energy_per_atom",
68
+ "band_gap",
69
+ "e_above_hull",
70
+ "mu_b",
71
+ "bulk modulus",
72
+ "shear modulus",
73
+ "elastic anisotropy",
74
+ "U0",
75
+ "HOMO",
76
+ "LUMO",
77
+ "R2",
78
+ "ZPVE",
79
+ "omega1",
80
+ "mu",
81
+ "alpha",
82
+ "homo",
83
+ "lumo",
84
+ "gap",
85
+ "r2",
86
+ "zpve",
87
+ "U",
88
+ "H",
89
+ "G",
90
+ "Cv",
91
+ "A",
92
+ "B",
93
+ "C",
94
+ "all",
95
+ "target",
96
+ "max_efg",
97
+ "avg_elec_mass",
98
+ "avg_hole_mass",
99
+ "_oqmd_band_gap",
100
+ "_oqmd_delta_e",
101
+ "_oqmd_stability",
102
+ "edos_up",
103
+ "pdos_elast",
104
+ "bandgap",
105
+ "energy_total",
106
+ "net_magmom",
107
+ "b3lyp_homo",
108
+ "b3lyp_lumo",
109
+ "b3lyp_gap",
110
+ "b3lyp_scharber_pce",
111
+ "b3lyp_scharber_voc",
112
+ "b3lyp_scharber_jsc",
113
+ "log_kd_ki",
114
+ "max_co2_adsp",
115
+ "min_co2_adsp",
116
+ "lcd",
117
+ "pld",
118
+ "void_fraction",
119
+ "surface_area_m2g",
120
+ "surface_area_m2cm3",
121
+ "indir_gap",
122
+ "f_enp",
123
+ "final_energy",
124
+ "energy_per_atom",
125
+ "ead",
126
+ ]
127
+
128
+
129
+ class TrainingConfig(BaseSettings):
130
+ """Training config defaults and validation."""
131
+
132
+ version: str = VERSION
133
+
134
+ # dataset configuration
135
+ dataset: Literal[
136
+ "dft_3d",
137
+ "jdft_3d-8-18-2021",
138
+ "dft_2d",
139
+ "megnet",
140
+ "megnet2",
141
+ "mp_3d_2020",
142
+ "qm9",
143
+ "qm9_dgl",
144
+ "qm9_std_jctc",
145
+ "user_data",
146
+ "oqmd_3d_no_cfid",
147
+ "edos_up",
148
+ "edos_pdos",
149
+ "qmof",
150
+ "qe_tb",
151
+ "hmof",
152
+ "hpov",
153
+ "pdbbind",
154
+ "pdbbind_core",
155
+ "tinnet_OH",
156
+ "tinnet_O",
157
+ "tinnet_N",
158
+ ] = "dft_3d"
159
+ target: TARGET_ENUM = "exfoliation_energy"
160
+ atom_features: Literal["basic", "atomic_number", "cfid", "cgcnn"] = "cgcnn"
161
+ neighbor_strategy: Literal[
162
+ "k-nearest",
163
+ "voronoi",
164
+ "radius_graph",
165
+ "radius_graph_jarvis",
166
+ "fast_graph",
167
+ "torch_graph",
168
+ "pure_torch",
169
+ ] = "k-nearest"
170
+ id_tag: Literal["jid", "id", "_oqmd_entry_id"] = "jid"
171
+
172
+ # training configuration
173
+ dtype: str = "float32"
174
+ random_seed: Optional[int] = 123
175
+ classification_threshold: Optional[float] = None
176
+ # target_range: Optional[List] = None
177
+ n_val: Optional[int] = None
178
+ n_test: Optional[int] = None
179
+ n_train: Optional[int] = None
180
+ train_ratio: Optional[float] = 0.8
181
+ val_ratio: Optional[float] = 0.1
182
+ test_ratio: Optional[float] = 0.1
183
+ target_multiplication_factor: Optional[float] = None
184
+ epochs: int = 300
185
+ batch_size: int = 64
186
+ gpu_memory_fraction: Optional[float] = None
187
+ use_amp: bool = False # bf16 mixed precision (A100/H100/RTX 30+)
188
+ # DDP tuning. find_unused_parameters=True is slow; enable only if
189
+ # your model has conditional branches whose gradients vary per step.
190
+ ddp_find_unused_parameters: bool = False
191
+ # Resume optimizer/scheduler/epoch from <output_dir>/current_state.pt if
192
+ # present. Lets a run that hit the walltime continue with a single
193
+ # continuous LR schedule instead of restarting it (weights alone are
194
+ # restored via --restart_model_path, which does not restore these).
195
+ resume_checkpoint: bool = False
196
+ # LR-schedule horizon in epochs, independent of how many epochs this job
197
+ # runs (`epochs`). Set it to the FINAL target when a run is split into
198
+ # resumed segments so OneCycle spans the whole run and stays continuous
199
+ # across restarts. None => use `epochs` (the single-job default).
200
+ lr_total_epochs: Optional[int] = None
201
+ # When True, forces cuDNN determinism (slower). Decoupled from seed so
202
+ # you can seed for reproducibility without paying the speed cost.
203
+ deterministic: bool = False
204
+ weight_decay: float = 0
205
+ learning_rate: float = 1e-2
206
+ filename: str = "sample"
207
+ warmup_steps: int = 2000
208
+ criterion: Literal["mse", "l1", "poisson", "zig"] = "mse"
209
+ optimizer: Literal["adamw", "sgd"] = "adamw"
210
+ scheduler: Literal["onecycle", "none"] = "onecycle"
211
+ pin_memory: bool = False
212
+ save_dataloader: bool = False
213
+ write_checkpoint: bool = True
214
+ write_predictions: bool = True
215
+ store_outputs: bool = True
216
+ progress: bool = True
217
+ log_tensorboard: bool = False
218
+ standard_scalar_and_pca: bool = False
219
+ use_canonize: bool = True
220
+ compute_line_graph: bool = True
221
+ num_workers: int = 4
222
+ cutoff: float = 5.0
223
+ cutoff_extra: float = 3.0
224
+ # Separate 3-body cutoff used by neighbor_strategy="pure_torch".
225
+ # When None, defaults to `cutoff`. Must be <= cutoff.
226
+ three_body_cutoff: Optional[float] = 3.5
227
+ max_neighbors: Optional[int] = 12
228
+ keep_data_order: bool = True
229
+ normalize_graph_level_loss: bool = False
230
+ distributed: bool = False
231
+ data_parallel: bool = False
232
+ n_early_stopping: Optional[int] = None # typically 50
233
+ output_dir: str = os.path.abspath(".")
234
+ use_lmdb: bool = True
235
+ # When True, reuse an existing LMDB cache on disk (fast, but the
236
+ # cache must match the current model backend + graph config).
237
+ # Default False: always rebuild from scratch for safety.
238
+ read_existing: bool = False
239
+ # alignn_layers: int = 4
240
+ # gcn_layers: int =4
241
+ # edge_input_features: int= 80
242
+ # hidden_features: int= 256
243
+ # triplet_input_features: int=40
244
+ # embedding_features: int=64
245
+
246
+ # model configuration
247
+ model: Union[
248
+ ALIGNNConfig,
249
+ ALIGNNAtomWiseConfig,
250
+ ALIGNNAtomWisePureConfig,
251
+ ALIGNNAtomWisePureSmoothConfig,
252
+ eALIGNNAtomWiseConfig,
253
+ ] = ALIGNNAtomWiseConfig(name="alignn_atomwise")