goldilocks-core 0.1.0__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.
Files changed (128) hide show
  1. goldilocks_core-0.1.0/LICENSE +28 -0
  2. goldilocks_core-0.1.0/PKG-INFO +136 -0
  3. goldilocks_core-0.1.0/README.md +114 -0
  4. goldilocks_core-0.1.0/pyproject.toml +266 -0
  5. goldilocks_core-0.1.0/setup.cfg +4 -0
  6. goldilocks_core-0.1.0/src/goldilocks_core/__init__.py +17 -0
  7. goldilocks_core-0.1.0/src/goldilocks_core/advisors/__init__.py +0 -0
  8. goldilocks_core-0.1.0/src/goldilocks_core/advisors/boundary.py +132 -0
  9. goldilocks_core-0.1.0/src/goldilocks_core/advisors/convergence.py +190 -0
  10. goldilocks_core-0.1.0/src/goldilocks_core/advisors/cutoffs.py +154 -0
  11. goldilocks_core-0.1.0/src/goldilocks_core/advisors/dos.py +125 -0
  12. goldilocks_core-0.1.0/src/goldilocks_core/advisors/electron_count.py +72 -0
  13. goldilocks_core-0.1.0/src/goldilocks_core/advisors/functional.py +63 -0
  14. goldilocks_core-0.1.0/src/goldilocks_core/advisors/hubbard_u.py +319 -0
  15. goldilocks_core-0.1.0/src/goldilocks_core/advisors/job_resources.py +328 -0
  16. goldilocks_core-0.1.0/src/goldilocks_core/advisors/k_sampling.py +330 -0
  17. goldilocks_core-0.1.0/src/goldilocks_core/advisors/magnetic_config.py +654 -0
  18. goldilocks_core-0.1.0/src/goldilocks_core/advisors/magnetic_ordering_ml.py +204 -0
  19. goldilocks_core-0.1.0/src/goldilocks_core/advisors/n_irr_k.py +82 -0
  20. goldilocks_core-0.1.0/src/goldilocks_core/advisors/nbnd.py +219 -0
  21. goldilocks_core-0.1.0/src/goldilocks_core/advisors/occupations.py +209 -0
  22. goldilocks_core-0.1.0/src/goldilocks_core/advisors/parallelisation.py +272 -0
  23. goldilocks_core-0.1.0/src/goldilocks_core/advisors/pseudo_selection.py +238 -0
  24. goldilocks_core-0.1.0/src/goldilocks_core/advisors/relax.py +394 -0
  25. goldilocks_core-0.1.0/src/goldilocks_core/advisors/size.py +150 -0
  26. goldilocks_core-0.1.0/src/goldilocks_core/advisors/vdw_method.py +158 -0
  27. goldilocks_core-0.1.0/src/goldilocks_core/advisors/warning_catalogue.py +43 -0
  28. goldilocks_core-0.1.0/src/goldilocks_core/analysis/__init__.py +0 -0
  29. goldilocks_core-0.1.0/src/goldilocks_core/analysis/composition.py +61 -0
  30. goldilocks_core-0.1.0/src/goldilocks_core/analysis/geometry.py +65 -0
  31. goldilocks_core-0.1.0/src/goldilocks_core/analysis/is_magnetic.py +144 -0
  32. goldilocks_core-0.1.0/src/goldilocks_core/analysis/is_metal.py +85 -0
  33. goldilocks_core-0.1.0/src/goldilocks_core/analysis/needs_correlation.py +73 -0
  34. goldilocks_core-0.1.0/src/goldilocks_core/analysis/needs_soc.py +79 -0
  35. goldilocks_core-0.1.0/src/goldilocks_core/analysis/symmetry.py +48 -0
  36. goldilocks_core-0.1.0/src/goldilocks_core/assets/__init__.py +0 -0
  37. goldilocks_core-0.1.0/src/goldilocks_core/assets/download.py +196 -0
  38. goldilocks_core-0.1.0/src/goldilocks_core/assets/profiles.py +21 -0
  39. goldilocks_core-0.1.0/src/goldilocks_core/assets/pseudopotentials/__init__.py +0 -0
  40. goldilocks_core-0.1.0/src/goldilocks_core/assets/pseudopotentials/importers.py +684 -0
  41. goldilocks_core-0.1.0/src/goldilocks_core/assets/pseudopotentials/registry.py +277 -0
  42. goldilocks_core-0.1.0/src/goldilocks_core/assets/pseudopotentials/registry.toml +642 -0
  43. goldilocks_core-0.1.0/src/goldilocks_core/assets/pseudopotentials/upf.py +459 -0
  44. goldilocks_core-0.1.0/src/goldilocks_core/assets/records.py +217 -0
  45. goldilocks_core-0.1.0/src/goldilocks_core/assets/runtime.py +110 -0
  46. goldilocks_core-0.1.0/src/goldilocks_core/assets/store.py +367 -0
  47. goldilocks_core-0.1.0/src/goldilocks_core/bundle.py +314 -0
  48. goldilocks_core-0.1.0/src/goldilocks_core/capabilities.py +916 -0
  49. goldilocks_core-0.1.0/src/goldilocks_core/checks.py +314 -0
  50. goldilocks_core-0.1.0/src/goldilocks_core/cli/__init__.py +0 -0
  51. goldilocks_core-0.1.0/src/goldilocks_core/cli/_assets.py +90 -0
  52. goldilocks_core-0.1.0/src/goldilocks_core/cli/_capabilities.py +62 -0
  53. goldilocks_core-0.1.0/src/goldilocks_core/cli/_common.py +106 -0
  54. goldilocks_core-0.1.0/src/goldilocks_core/cli/_explain.py +77 -0
  55. goldilocks_core-0.1.0/src/goldilocks_core/cli/_inspect.py +37 -0
  56. goldilocks_core-0.1.0/src/goldilocks_core/cli/_magnetic_orderings.py +70 -0
  57. goldilocks_core-0.1.0/src/goldilocks_core/cli/_models.py +48 -0
  58. goldilocks_core-0.1.0/src/goldilocks_core/cli/_run.py +165 -0
  59. goldilocks_core-0.1.0/src/goldilocks_core/cli/_serve.py +41 -0
  60. goldilocks_core-0.1.0/src/goldilocks_core/cli/_settings.py +33 -0
  61. goldilocks_core-0.1.0/src/goldilocks_core/cli/core.py +98 -0
  62. goldilocks_core-0.1.0/src/goldilocks_core/examples/__init__.py +0 -0
  63. goldilocks_core-0.1.0/src/goldilocks_core/examples/structures/Fe_bcc.cif +28 -0
  64. goldilocks_core-0.1.0/src/goldilocks_core/examples/structures/Pt_fcc.cif +30 -0
  65. goldilocks_core-0.1.0/src/goldilocks_core/examples/structures/README.md +25 -0
  66. goldilocks_core-0.1.0/src/goldilocks_core/examples/structures/Si.cif +34 -0
  67. goldilocks_core-0.1.0/src/goldilocks_core/examples/structures.py +24 -0
  68. goldilocks_core-0.1.0/src/goldilocks_core/failures.py +25 -0
  69. goldilocks_core-0.1.0/src/goldilocks_core/functionals.py +39 -0
  70. goldilocks_core-0.1.0/src/goldilocks_core/generation/__init__.py +0 -0
  71. goldilocks_core-0.1.0/src/goldilocks_core/generation/errors.py +5 -0
  72. goldilocks_core-0.1.0/src/goldilocks_core/generation/files.py +14 -0
  73. goldilocks_core-0.1.0/src/goldilocks_core/generation/quantum_espresso/__init__.py +0 -0
  74. goldilocks_core-0.1.0/src/goldilocks_core/generation/quantum_espresso/dos.py +59 -0
  75. goldilocks_core-0.1.0/src/goldilocks_core/generation/quantum_espresso/namelists.py +109 -0
  76. goldilocks_core-0.1.0/src/goldilocks_core/generation/quantum_espresso/relax.py +264 -0
  77. goldilocks_core-0.1.0/src/goldilocks_core/generation/quantum_espresso/scf.py +572 -0
  78. goldilocks_core-0.1.0/src/goldilocks_core/inputs/__init__.py +0 -0
  79. goldilocks_core-0.1.0/src/goldilocks_core/inputs/hpc.py +196 -0
  80. goldilocks_core-0.1.0/src/goldilocks_core/inputs/overrides.py +37 -0
  81. goldilocks_core-0.1.0/src/goldilocks_core/inputs/profiles/__init__.py +4 -0
  82. goldilocks_core-0.1.0/src/goldilocks_core/inputs/profiles/scarf.toml +48 -0
  83. goldilocks_core-0.1.0/src/goldilocks_core/inputs/structure.py +305 -0
  84. goldilocks_core-0.1.0/src/goldilocks_core/inputs/task.py +28 -0
  85. goldilocks_core-0.1.0/src/goldilocks_core/kmesh.py +248 -0
  86. goldilocks_core-0.1.0/src/goldilocks_core/ml/__init__.py +0 -0
  87. goldilocks_core-0.1.0/src/goldilocks_core/ml/models.py +264 -0
  88. goldilocks_core-0.1.0/src/goldilocks_core/ml/predict.py +130 -0
  89. goldilocks_core-0.1.0/src/goldilocks_core/ml/registry.toml +198 -0
  90. goldilocks_core-0.1.0/src/goldilocks_core/plan.py +61 -0
  91. goldilocks_core-0.1.0/src/goldilocks_core/resolution.py +249 -0
  92. goldilocks_core-0.1.0/src/goldilocks_core/serialization.py +102 -0
  93. goldilocks_core-0.1.0/src/goldilocks_core/server/__init__.py +0 -0
  94. goldilocks_core-0.1.0/src/goldilocks_core/server/_handlers.py +184 -0
  95. goldilocks_core-0.1.0/src/goldilocks_core/server/documents.py +105 -0
  96. goldilocks_core-0.1.0/src/goldilocks_core/server/http.py +196 -0
  97. goldilocks_core-0.1.0/src/goldilocks_core/server/mcp.py +156 -0
  98. goldilocks_core-0.1.0/src/goldilocks_core/server/readiness.py +134 -0
  99. goldilocks_core-0.1.0/src/goldilocks_core/service/__init__.py +130 -0
  100. goldilocks_core-0.1.0/src/goldilocks_core/service/_advice.py +140 -0
  101. goldilocks_core-0.1.0/src/goldilocks_core/service/_analysis.py +97 -0
  102. goldilocks_core-0.1.0/src/goldilocks_core/service/_bundle.py +91 -0
  103. goldilocks_core-0.1.0/src/goldilocks_core/service/_dos.py +240 -0
  104. goldilocks_core-0.1.0/src/goldilocks_core/service/_generate.py +106 -0
  105. goldilocks_core-0.1.0/src/goldilocks_core/service/_magnetic_orderings.py +230 -0
  106. goldilocks_core-0.1.0/src/goldilocks_core/service/_pipeline.py +113 -0
  107. goldilocks_core-0.1.0/src/goldilocks_core/service/_pseudo.py +144 -0
  108. goldilocks_core-0.1.0/src/goldilocks_core/service/_relax.py +153 -0
  109. goldilocks_core-0.1.0/src/goldilocks_core/service/_step.py +104 -0
  110. goldilocks_core-0.1.0/src/goldilocks_core/service/_step_kpoints.py +143 -0
  111. goldilocks_core-0.1.0/src/goldilocks_core/service/_step_resources.py +119 -0
  112. goldilocks_core-0.1.0/src/goldilocks_core/service/_system.py +198 -0
  113. goldilocks_core-0.1.0/src/goldilocks_core/service/_system_overrides.py +43 -0
  114. goldilocks_core-0.1.0/src/goldilocks_core/set_overrides.py +234 -0
  115. goldilocks_core-0.1.0/src/goldilocks_core/step_settings.py +117 -0
  116. goldilocks_core-0.1.0/src/goldilocks_core/steps.py +107 -0
  117. goldilocks_core-0.1.0/src/goldilocks_core/submission/__init__.py +0 -0
  118. goldilocks_core-0.1.0/src/goldilocks_core/submission/errors.py +14 -0
  119. goldilocks_core-0.1.0/src/goldilocks_core/submission/slurm.py +153 -0
  120. goldilocks_core-0.1.0/src/goldilocks_core/system_settings.py +56 -0
  121. goldilocks_core-0.1.0/src/goldilocks_core/types.py +36 -0
  122. goldilocks_core-0.1.0/src/goldilocks_core/validation.py +36 -0
  123. goldilocks_core-0.1.0/src/goldilocks_core.egg-info/PKG-INFO +136 -0
  124. goldilocks_core-0.1.0/src/goldilocks_core.egg-info/SOURCES.txt +126 -0
  125. goldilocks_core-0.1.0/src/goldilocks_core.egg-info/dependency_links.txt +1 -0
  126. goldilocks_core-0.1.0/src/goldilocks_core.egg-info/entry_points.txt +2 -0
  127. goldilocks_core-0.1.0/src/goldilocks_core.egg-info/requires.txt +14 -0
  128. goldilocks_core-0.1.0/src/goldilocks_core.egg-info/top_level.txt +1 -0
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, UKRI Science and Technology Facilities Council
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,136 @@
1
+ Metadata-Version: 2.4
2
+ Name: goldilocks-core
3
+ Version: 0.1.0
4
+ Summary: Materials machine learning tools for recommending DFT calculation inputs.
5
+ License-Expression: BSD-3-Clause
6
+ Requires-Python: >=3.12
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: ase>=3.28
10
+ Requires-Dist: numpy>=2.4.4
11
+ Requires-Dist: pandas>=2.0
12
+ Requires-Dist: pymatgen>=2026.3.23
13
+ Requires-Dist: requests>=2.32
14
+ Requires-Dist: goldilocks-ml==0.2.3
15
+ Requires-Dist: pydantic>=2.12
16
+ Provides-Extra: http
17
+ Requires-Dist: fastapi; extra == "http"
18
+ Requires-Dist: uvicorn; extra == "http"
19
+ Provides-Extra: mcp
20
+ Requires-Dist: mcp; extra == "mcp"
21
+ Dynamic: license-file
22
+
23
+ # goldilocks-core
24
+
25
+ Goldilocks recommends settings for density functional theory (DFT) calculations
26
+ and generates Quantum ESPRESSO input files (SCF, DOS, relaxation, and
27
+ variable-cell relaxation) from a crystal structure.
28
+
29
+ ## Installation
30
+
31
+ Not published to PyPI yet -- clone the repository. Install
32
+ [uv](https://docs.astral.sh/uv/getting-started/installation/) first:
33
+
34
+ ```bash
35
+ git clone https://github.com/junwen94/goldilocks-core.git
36
+ cd goldilocks-core
37
+ uv sync
38
+ ```
39
+
40
+ ## Try it
41
+
42
+ ### Start the Workbench
43
+
44
+ With Node.js 24 or newer installed, run:
45
+
46
+ ```bash
47
+ uv sync --extra http
48
+ npm --prefix web ci
49
+ uv run goldilocks assets install workbench
50
+ uv run --extra http poe workbench
51
+ ```
52
+
53
+ The asset step installs the models and pseudopotential tables. Open
54
+ **http://127.0.0.1:5173**, upload a CIF or POSCAR, review the recommended
55
+ settings, and download the generated inputs.
56
+
57
+ For a built frontend instead, stop the development servers and run:
58
+
59
+ ```bash
60
+ uv run --extra http poe stage
61
+ ```
62
+
63
+ Then open **http://127.0.0.1:8000**. See the [Workbench guide](web/README.md)
64
+ for Docker and development checks.
65
+
66
+ #### With mMACE (ML-backed magnetism features)
67
+
68
+ Without any extra setup, magnetism classification (`is_magnetic`) and
69
+ magnetic-ordering ranking run at a heuristic/LLM tier. To get the real ML
70
+ tier, install `mace`/`e3nn`/`sphericart` and a checkpoint file once, manually
71
+ -- none of this can ever be a `pip`/`uv` extra (the `mace` fork it needs has
72
+ no PyPI release):
73
+
74
+ ```bash
75
+ uv pip install ase==3.28.0 e3nn==0.4.4 sphericart==1.0.9 sphericart-torch==1.0.9
76
+ uv pip install "mace-torch @ git+https://github.com/CheukHinHoJerry/mace.git@19cdf6692c48e068a24e06cfe1ffc670e8aea3dd"
77
+ mkdir -p ~/.local/share/goldilocks/mmace
78
+ curl -L -o ~/.local/share/goldilocks/mmace/mace_matpes_pbe_baseline_run-3.model \
79
+ https://data-collections.psdi.ac.uk/api/records/1g8rw-q8128/files/mace_matpes_pbe_baseline_run-3.model/content
80
+ export GOLDILOCKS_MACE_BACKBONE=~/.local/share/goldilocks/mmace/mace_matpes_pbe_baseline_run-3.model
81
+ ```
82
+
83
+ Then start the Workbench as above **in the same shell** (the backend only
84
+ picks up `GOLDILOCKS_MACE_BACKBONE` if it's set before launch). Load a
85
+ magnetic structure (e.g.
86
+ `src/goldilocks_core/examples/structures/Fe_bcc.cif`) and check the
87
+ **Analysis** column's "is magnetic" field: its caption switches to
88
+ **"Goldilocks-ML prediction"** once the `ml` tier is live.
89
+
90
+ Two gotchas worth knowing up front: `uv sync` silently removes the two
91
+ manually-installed packages again (they're not in `uv.lock`) -- re-run the
92
+ `uv pip install` lines above after any `uv sync`; and the Workbench's own
93
+ "Run mMACE" ranking button is currently broken
94
+ ([stfc/goldilocks-ml#95](https://github.com/stfc/goldilocks-ml/issues/95)) --
95
+ use `uv run goldilocks magnetic-orderings --rank-with-mmace` from the CLI for
96
+ ranking instead. Checksum verification and full troubleshooting:
97
+ [mMACE setup](docs/mmace-setup.md).
98
+
99
+ ### Generate inputs from the command line
100
+
101
+ Download the prediction models and default pseudopotential table, then generate
102
+ inputs for the bundled silicon structure:
103
+
104
+ ```bash
105
+ uv run goldilocks assets install default
106
+ uv run goldilocks run src/goldilocks_core/examples/structures/Si.cif --out si-run
107
+ ```
108
+
109
+ Open `si-run/scf.in` to see the input. The directory also contains the
110
+ pseudopotential file, a submission script, and `goldilocks.json` (full
111
+ provenance for every setting).
112
+
113
+ Treat the recommended settings as a starting point: review warnings and check
114
+ convergence for your calculation. The [quickstart](docs/quickstart.md) explains
115
+ the output and how to run it.
116
+
117
+ ## Guides and reference
118
+
119
+ - [First calculation](docs/quickstart.md) — generate, check, and run an input.
120
+ - [Python API](docs/tutorial.md) — use Goldilocks in a script.
121
+ - [Recommendations](docs/science.md) — understand the choices and their limits.
122
+ - [Pseudopotentials](docs/pseudopotentials.md) — choose a table and understand
123
+ automatic selection.
124
+ - [CLI reference](docs/cli.md) — commands and options.
125
+ - [mMACE setup](docs/mmace-setup.md) — enable the ML-backed magnetism
126
+ features.
127
+ - [Scientific conventions](docs/conventions.md) — units and numerical
128
+ definitions.
129
+ - [Contributing](docs/architecture.md) — code layout and development checks.
130
+
131
+ ## Licence
132
+
133
+ Code: [BSD 3-Clause](LICENSE). Documentation under `docs/` and example
134
+ structures: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
135
+ Downloaded pseudopotentials retain their
136
+ [upstream licences](docs/pseudopotentials.md#licences-and-citations).
@@ -0,0 +1,114 @@
1
+ # goldilocks-core
2
+
3
+ Goldilocks recommends settings for density functional theory (DFT) calculations
4
+ and generates Quantum ESPRESSO input files (SCF, DOS, relaxation, and
5
+ variable-cell relaxation) from a crystal structure.
6
+
7
+ ## Installation
8
+
9
+ Not published to PyPI yet -- clone the repository. Install
10
+ [uv](https://docs.astral.sh/uv/getting-started/installation/) first:
11
+
12
+ ```bash
13
+ git clone https://github.com/junwen94/goldilocks-core.git
14
+ cd goldilocks-core
15
+ uv sync
16
+ ```
17
+
18
+ ## Try it
19
+
20
+ ### Start the Workbench
21
+
22
+ With Node.js 24 or newer installed, run:
23
+
24
+ ```bash
25
+ uv sync --extra http
26
+ npm --prefix web ci
27
+ uv run goldilocks assets install workbench
28
+ uv run --extra http poe workbench
29
+ ```
30
+
31
+ The asset step installs the models and pseudopotential tables. Open
32
+ **http://127.0.0.1:5173**, upload a CIF or POSCAR, review the recommended
33
+ settings, and download the generated inputs.
34
+
35
+ For a built frontend instead, stop the development servers and run:
36
+
37
+ ```bash
38
+ uv run --extra http poe stage
39
+ ```
40
+
41
+ Then open **http://127.0.0.1:8000**. See the [Workbench guide](web/README.md)
42
+ for Docker and development checks.
43
+
44
+ #### With mMACE (ML-backed magnetism features)
45
+
46
+ Without any extra setup, magnetism classification (`is_magnetic`) and
47
+ magnetic-ordering ranking run at a heuristic/LLM tier. To get the real ML
48
+ tier, install `mace`/`e3nn`/`sphericart` and a checkpoint file once, manually
49
+ -- none of this can ever be a `pip`/`uv` extra (the `mace` fork it needs has
50
+ no PyPI release):
51
+
52
+ ```bash
53
+ uv pip install ase==3.28.0 e3nn==0.4.4 sphericart==1.0.9 sphericart-torch==1.0.9
54
+ uv pip install "mace-torch @ git+https://github.com/CheukHinHoJerry/mace.git@19cdf6692c48e068a24e06cfe1ffc670e8aea3dd"
55
+ mkdir -p ~/.local/share/goldilocks/mmace
56
+ curl -L -o ~/.local/share/goldilocks/mmace/mace_matpes_pbe_baseline_run-3.model \
57
+ https://data-collections.psdi.ac.uk/api/records/1g8rw-q8128/files/mace_matpes_pbe_baseline_run-3.model/content
58
+ export GOLDILOCKS_MACE_BACKBONE=~/.local/share/goldilocks/mmace/mace_matpes_pbe_baseline_run-3.model
59
+ ```
60
+
61
+ Then start the Workbench as above **in the same shell** (the backend only
62
+ picks up `GOLDILOCKS_MACE_BACKBONE` if it's set before launch). Load a
63
+ magnetic structure (e.g.
64
+ `src/goldilocks_core/examples/structures/Fe_bcc.cif`) and check the
65
+ **Analysis** column's "is magnetic" field: its caption switches to
66
+ **"Goldilocks-ML prediction"** once the `ml` tier is live.
67
+
68
+ Two gotchas worth knowing up front: `uv sync` silently removes the two
69
+ manually-installed packages again (they're not in `uv.lock`) -- re-run the
70
+ `uv pip install` lines above after any `uv sync`; and the Workbench's own
71
+ "Run mMACE" ranking button is currently broken
72
+ ([stfc/goldilocks-ml#95](https://github.com/stfc/goldilocks-ml/issues/95)) --
73
+ use `uv run goldilocks magnetic-orderings --rank-with-mmace` from the CLI for
74
+ ranking instead. Checksum verification and full troubleshooting:
75
+ [mMACE setup](docs/mmace-setup.md).
76
+
77
+ ### Generate inputs from the command line
78
+
79
+ Download the prediction models and default pseudopotential table, then generate
80
+ inputs for the bundled silicon structure:
81
+
82
+ ```bash
83
+ uv run goldilocks assets install default
84
+ uv run goldilocks run src/goldilocks_core/examples/structures/Si.cif --out si-run
85
+ ```
86
+
87
+ Open `si-run/scf.in` to see the input. The directory also contains the
88
+ pseudopotential file, a submission script, and `goldilocks.json` (full
89
+ provenance for every setting).
90
+
91
+ Treat the recommended settings as a starting point: review warnings and check
92
+ convergence for your calculation. The [quickstart](docs/quickstart.md) explains
93
+ the output and how to run it.
94
+
95
+ ## Guides and reference
96
+
97
+ - [First calculation](docs/quickstart.md) — generate, check, and run an input.
98
+ - [Python API](docs/tutorial.md) — use Goldilocks in a script.
99
+ - [Recommendations](docs/science.md) — understand the choices and their limits.
100
+ - [Pseudopotentials](docs/pseudopotentials.md) — choose a table and understand
101
+ automatic selection.
102
+ - [CLI reference](docs/cli.md) — commands and options.
103
+ - [mMACE setup](docs/mmace-setup.md) — enable the ML-backed magnetism
104
+ features.
105
+ - [Scientific conventions](docs/conventions.md) — units and numerical
106
+ definitions.
107
+ - [Contributing](docs/architecture.md) — code layout and development checks.
108
+
109
+ ## Licence
110
+
111
+ Code: [BSD 3-Clause](LICENSE). Documentation under `docs/` and example
112
+ structures: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
113
+ Downloaded pseudopotentials retain their
114
+ [upstream licences](docs/pseudopotentials.md#licences-and-citations).
@@ -0,0 +1,266 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "goldilocks-core"
7
+ version = "0.1.0"
8
+ description = "Materials machine learning tools for recommending DFT calculation inputs."
9
+ readme = "README.md"
10
+ license = "BSD-3-Clause"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.12"
13
+ dependencies = [
14
+ # v2: generation/quantum_espresso/namelists.py uses only ase.io.espresso_namelist's
15
+ # Namelist class (a flat-dict -> QE namelist-text formatter with no Atoms/magnetic-
16
+ # moment logic at all) -- not ase.io.espresso.write_espresso_in, and not the
17
+ # Espresso calculator, both of which derive/overwrite starting_magnetization from
18
+ # atoms.get_initial_magnetic_moments() whenever nspin==2, unconditionally clobbering
19
+ # any value already resolved by advisors/magnetic_config.py (verified against
20
+ # installed ase 3.28, 2026-09-14; goldilocks-core-design.md:4220's "only use ASE at
21
+ # the namelists.py translation layer" insertion point).
22
+ "ase>=3.28",
23
+ "numpy>=2.4.4",
24
+ "pandas>=2.0",
25
+ "pymatgen>=2026.3.23",
26
+ "requests>=2.32",
27
+ # The default k-points/metallicity models (QRF + CGCNN) are a core
28
+ # capability, so their ML stack ships in the base install (decision:
29
+ # stfc/goldilocks-core#32) -- via goldilocks-ml itself (v2 #11) rather
30
+ # than duplicating dscribe/matminer/scikit-learn/sklearn-quantile/
31
+ # torch/torch-geometric as separate pins here, which would drift the two
32
+ # packages apart the same way this exact torch pin already had to be
33
+ # unwound once (see goldilocks-ml's own comment: torch pinned to exactly
34
+ # 2.10.0, both the lowest release patched against
35
+ # CVE-2026-24747/GHSA-63cw-57p8-fm3p and the highest is_magnetic's
36
+ # manually-installed sphericart-torch==1.0.9 tolerates -- goldilocks-
37
+ # core's own prior `torch>=2.13.0` pin predated that finding and would
38
+ # have conflicted with it outright). goldilocks-ml 0.2.0 dropped its
39
+ # `models` extra entirely -- everything is now a hard dependency of
40
+ # plain `goldilocks-ml`, so there is nothing left to select here either.
41
+ # torch-geometric requires torch; the base install resolves torch from
42
+ # the CPU-only PyTorch index so the workbench image doesn't ship ~3.5G
43
+ # of unused CUDA/nvidia libraries. GPU hosts pull the CUDA wheel via an
44
+ # index override (see [tool.uv] below), not the default resolution.
45
+ "goldilocks-ml==0.2.3",
46
+ # v2: contracts/ is pydantic BaseModel end to end (validation, serialization,
47
+ # OpenAPI/capabilities schema generation) -- promoted from the http/mcp
48
+ # extras to a core dependency (goldilocks-core-design.md S12, already decided).
49
+ "pydantic>=2.12",
50
+ ]
51
+
52
+ [project.optional-dependencies]
53
+ http = ["fastapi", "uvicorn"]
54
+ mcp = ["mcp"]
55
+ # is_magnetic classification and mMACE-based magnetic-ordering ranking
56
+ # (v2 #11, #87), additive on top of goldilocks-ml itself (a hard
57
+ # dependency, already in the base install above). goldilocks-ml 0.2.0 (released
58
+ # 2026-09-21) ships is_magnetic for real, so the base dependency above is
59
+ # now functionally reachable -- but there is still, and will permanently
60
+ # be, no installable extra for this repo to depend on here: goldilocks-ml
61
+ # has decided against ever shipping a `magnetism` extra at all, because it
62
+ # needs `mace` (a research collaborator's fork with no PyPI release, and
63
+ # PyPI's own upload validation rejects a direct git dependency in a
64
+ # published package's metadata regardless -- goldilocks-ml's own
65
+ # deposits/magnetism/is_magnetic/mace_mlp/VENDORING_TODO.md has the full
66
+ # story). is_magnetic needs the same manual `mace` install goldilocks-ml's
67
+ # own README documents ("Use the is_magnetic classifier"); mMACE-based
68
+ # ordering ranking additionally needs a manually-configured
69
+ # GOLDILOCKS_MACE_BACKBONE checkpoint (advisors/magnetic_ordering_ml.py).
70
+ # Neither of which any `pip install goldilocks-core[...]` extra could ever
71
+ # make installable end-to-end -- this is a permanent, upstream-acknowledged
72
+ # manual step, not a temporary gap this repo's own packaging can close.
73
+
74
+ [project.scripts]
75
+ goldilocks = "goldilocks_core.cli.core:main"
76
+
77
+ [tool.poe.tasks.fmt]
78
+ help = "Format src, tests, and scripts with ruff"
79
+ cmd = "ruff format src tests scripts"
80
+
81
+ [tool.poe.tasks.lint]
82
+ help = "Check style and complexity, matching the CI gate"
83
+ sequence = [
84
+ { cmd = "ruff check src tests scripts" },
85
+ { cmd = "ruff format --check src tests scripts" },
86
+ { cmd = "python scripts/check_complexity.py" },
87
+ ]
88
+
89
+ [tool.poe.tasks.test]
90
+ help = "Run the pytest suite"
91
+ cmd = "pytest"
92
+
93
+ [tool.poe.tasks.check]
94
+ help = "Lint and test, the local pre-PR gate"
95
+ sequence = [
96
+ { ref = "lint" },
97
+ { ref = "test" },
98
+ ]
99
+
100
+ [tool.poe.tasks.serve]
101
+ help = "Install assets and serve the Core HTTP backend on :8000"
102
+ shell = """
103
+ if curl -s -m1 http://127.0.0.1:8000/ >/dev/null 2>&1; then
104
+ echo "port 8000 is already in use - stop the other server (poe workbench, poe serve, or poe stage)" >&2
105
+ exit 1
106
+ fi
107
+ set -e
108
+ goldilocks assets install workbench
109
+ exec goldilocks serve http --host 127.0.0.1 --port 8000
110
+ """
111
+
112
+ [tool.poe.tasks.stage]
113
+ help = "Build the Workbench bundle and serve it from the Core HTTP process on :8000"
114
+ shell = """
115
+ if curl -s -m1 http://127.0.0.1:8000/ >/dev/null 2>&1; then
116
+ echo "port 8000 is already in use - stop the other server (poe workbench, poe serve, or poe stage)" >&2
117
+ exit 1
118
+ fi
119
+ set -e
120
+ cd web && npm run build
121
+ cd ..
122
+ goldilocks assets install workbench
123
+ exec goldilocks serve http --host 127.0.0.1 --port 8000 --static-root web/dist
124
+ """
125
+
126
+ [tool.poe.tasks.workbench]
127
+ help = "Install assets, serve the Core HTTP backend on :8000, and run the Vite dev server on :5173"
128
+ shell = """
129
+ if curl -s -m1 http://127.0.0.1:8000/ >/dev/null 2>&1; then
130
+ echo "port 8000 is already in use - stop the other server (poe workbench, poe serve, or poe stage)" >&2
131
+ exit 1
132
+ fi
133
+ set -e
134
+ goldilocks assets install workbench
135
+ goldilocks serve http --host 127.0.0.1 --port 8000 &
136
+ backend_pid=$!
137
+ trap 'kill "$backend_pid"' EXIT
138
+ cd web && npm run dev
139
+ """
140
+
141
+ [tool.poe.tasks.web-check]
142
+ help = "Lint, unit-test, and build the Workbench frontend"
143
+ shell = "cd web && npm run check"
144
+
145
+ [dependency-groups]
146
+ dev = [
147
+ "mkdocs>=1.6.1",
148
+ "mkdocs-material>=9.6.0",
149
+ "mutmut>=3.8.0",
150
+ "poethepoet>=0.35",
151
+ "pre-commit>=4.5.1",
152
+ "pytest>=9.0.3",
153
+ "pytest-cov>=7.1.0",
154
+ "ruff>=0.15.11",
155
+ ]
156
+
157
+ [tool.uv]
158
+ package = true
159
+
160
+ # PyTorch publishes CPU and CUDA wheels on separate indexes. Pin torch to the
161
+ # CPU index so container/workbench builds don't ship ~3.5G of unused CUDA/nvidia
162
+ # libraries. GPU hosts override with `uv sync --index-strategy unsafe-best-match
163
+ # --extra-index-url https://download.pytorch.org/whl/cu130` (or set
164
+ # UV_EXTRA_INDEX_URL to the cu130 index) to pull the CUDA wheel instead.
165
+ # torch-geometric and other torch-* packages stay on PyPI; only torch itself is
166
+ # re-sourced, since it's the one that drags in the nvidia/triton wheels.
167
+ [[tool.uv.index]]
168
+ name = "pytorch-cpu"
169
+ url = "https://download.pytorch.org/whl/cpu"
170
+ explicit = true
171
+
172
+ [tool.uv.sources]
173
+ torch = [
174
+ { index = "pytorch-cpu" },
175
+ ]
176
+
177
+ [tool.pytest.ini_options]
178
+ addopts = ["--strict-markers", "-ra"]
179
+ pythonpath = ["src"]
180
+ testpaths = ["tests"]
181
+ markers = [
182
+ "unit: isolated behavior with controlled collaborators",
183
+ "integration: workflows crossing real package boundaries",
184
+ "physics: scientific invariants checked independently of implementation",
185
+ ]
186
+
187
+ [tool.coverage.run]
188
+ branch = true
189
+ source = ["goldilocks_core"]
190
+ omit = ["/tmp/*"]
191
+
192
+ [tool.coverage.report]
193
+ exclude_also = [
194
+ "if TYPE_CHECKING:",
195
+ "raise NotImplementedError",
196
+ ]
197
+ show_missing = true
198
+ skip_covered = true
199
+
200
+ [tool.mutmut]
201
+ # process_isolation = "forkserver" (mutmut >=3.8.0) routes every mutant's
202
+ # fork/reap through one dedicated forkserver child, instead of the default
203
+ # ForkRunner's os.wait() in the main process -- which reaps *any* child, so an
204
+ # untracked pid (e.g. a leftover from the stats/generation phase) causes a
205
+ # bare `self._running.pop(pid)` KeyError (stfc/goldilocks-core#76). The
206
+ # forkserver's own reap loop explicitly ignores unknown pids instead of
207
+ # crashing. Lowering --max-children (ci.yml, #77) only reduced how often the
208
+ # race was hit; it could not fix a race that isn't about mutmut's own worker
209
+ # concurrency in the first place.
210
+ process_isolation = "forkserver"
211
+ # source_paths creates parent directories for nested files; also_copy does not.
212
+ # Copy nested test inputs without web/node_modules or build outputs.
213
+ source_paths = [
214
+ "src/goldilocks_core",
215
+ "web/README.md",
216
+ ".agents/skills/use-goldilocks/references/workflows.md",
217
+ ".agents/skills/use-goldilocks/references/qe-scf-template.md",
218
+ ]
219
+ # Documentation tests read these files and validate their relative links.
220
+ also_copy = ["README.md", "LICENSE", "docs"]
221
+ only_mutate = [
222
+ "src/goldilocks_core/advisors/pseudo_selection.py",
223
+ "src/goldilocks_core/functionals.py",
224
+ "src/goldilocks_core/generation/quantum_espresso/scf.py",
225
+ "src/goldilocks_core/kmesh.py",
226
+ "src/goldilocks_core/service/_pipeline.py",
227
+ ]
228
+ mutate_only_covered_lines = false
229
+ pytest_add_cli_args = ["-q"]
230
+
231
+ [tool.ruff]
232
+ target-version = "py312"
233
+
234
+ [tool.ruff.lint]
235
+ select = [
236
+ "E", "F", "I", # baseline
237
+ "B", # bugbear: real footguns
238
+ "UP", # modern python; ceremony prevention
239
+ "C4", # comprehensions over loops
240
+ "SIM", # collapse ceremony
241
+ "RET", # return discipline
242
+ "PIE", # useless constructs
243
+ "PERF", # needless work
244
+ "TID", # import hygiene, banned modules
245
+ "RUF", # ruff-specific: noqa discipline, mutable defaults
246
+ "BLE", # no blind exception catches
247
+ ]
248
+
249
+ [tool.ruff.lint.mccabe]
250
+ max-complexity = 10
251
+
252
+ [tool.ruff.lint.flake8-tidy-imports.banned-api]
253
+ "goldilocks_core.contracts".msg = "the contracts package was dissolved; import from the domain module that defines the name"
254
+
255
+ [tool.setuptools.package-data]
256
+ goldilocks_core = [
257
+ "ml/registry.toml",
258
+ "assets/pseudopotentials/registry.toml",
259
+ "inputs/profiles/*.toml",
260
+ "examples/structures/*.cif",
261
+ "examples/structures/README.md",
262
+ ]
263
+
264
+
265
+ [tool.ruff.lint.isort]
266
+ combine-as-imports = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,17 @@
1
+ """goldilocks_core: DFT input advice and generation for Quantum ESPRESSO.
2
+
3
+ Deliberately re-exports nothing (v2 epic 9, #9, cutover). v1's
4
+ ``__init__.py`` flattened its whole ``Service``/``compute``/
5
+ ``ComputeRequest`` surface here; v2 has no equivalent single facade to
6
+ re-export, by design (``service/__init__.py``'s own docstring: "the
7
+ public API stays flat" at *that* level, not this one). The real entry
8
+ points are the packages themselves:
9
+
10
+ - ``goldilocks_core.service`` -- ``advise``/``check``/``generate`` (and
11
+ the ``dos`` task's ``advise_dos``/``check_dos``/``generate_dos``), the
12
+ programmatic API
13
+ - ``goldilocks_core.cli`` -- the ``goldilocks`` command-line entry point
14
+ - ``goldilocks_core.server`` -- the HTTP and MCP transports
15
+ """
16
+
17
+ from __future__ import annotations