Jarvis-HEP-Sampler 1.0.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.
- jarvis_hep_sampler-1.0.0/LICENSE +21 -0
- jarvis_hep_sampler-1.0.0/MANIFEST.in +4 -0
- jarvis_hep_sampler-1.0.0/PKG-INFO +178 -0
- jarvis_hep_sampler-1.0.0/README.md +153 -0
- jarvis_hep_sampler-1.0.0/docs/README.md +3 -0
- jarvis_hep_sampler-1.0.0/docs/development/PLUGIN_AUTHORING.md +140 -0
- jarvis_hep_sampler-1.0.0/examples/MyLatinHypercube.py +42 -0
- jarvis_hep_sampler-1.0.0/examples/MyLatinHypercube.task.yaml +34 -0
- jarvis_hep_sampler-1.0.0/pyproject.toml +52 -0
- jarvis_hep_sampler-1.0.0/setup.cfg +4 -0
- jarvis_hep_sampler-1.0.0/src/Jarvis_HEP_Sampler.egg-info/PKG-INFO +178 -0
- jarvis_hep_sampler-1.0.0/src/Jarvis_HEP_Sampler.egg-info/SOURCES.txt +42 -0
- jarvis_hep_sampler-1.0.0/src/Jarvis_HEP_Sampler.egg-info/dependency_links.txt +1 -0
- jarvis_hep_sampler-1.0.0/src/Jarvis_HEP_Sampler.egg-info/requires.txt +2 -0
- jarvis_hep_sampler-1.0.0/src/Jarvis_HEP_Sampler.egg-info/top_level.txt +1 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/__init__.py +141 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/_check_restart.py +29 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/_version.py +1 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/contexts.py +69 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/errors.py +81 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/loader.py +237 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/log.py +97 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/metadata.py +210 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/options.py +243 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/output.py +139 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/py.typed +0 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/registry.py +516 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/session.py +347 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/streams.py +64 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/template.py +62 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/templates/independent.py.tmpl +47 -0
- jarvis_hep_sampler-1.0.0/src/jarvis_hep_sampler/testing.py +365 -0
- jarvis_hep_sampler-1.0.0/tests/__init__.py +0 -0
- jarvis_hep_sampler-1.0.0/tests/conftest.py +73 -0
- jarvis_hep_sampler-1.0.0/tests/test_error_boundaries.py +58 -0
- jarvis_hep_sampler-1.0.0/tests/test_loader.py +109 -0
- jarvis_hep_sampler-1.0.0/tests/test_metadata.py +94 -0
- jarvis_hep_sampler-1.0.0/tests/test_options.py +107 -0
- jarvis_hep_sampler-1.0.0/tests/test_package.py +36 -0
- jarvis_hep_sampler-1.0.0/tests/test_registry.py +489 -0
- jarvis_hep_sampler-1.0.0/tests/test_session.py +328 -0
- jarvis_hep_sampler-1.0.0/tests/test_stream_protocol.py +49 -0
- jarvis_hep_sampler-1.0.0/tests/test_streams_output.py +116 -0
- jarvis_hep_sampler-1.0.0/tests/test_template_and_testing.py +233 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pengxuan Zhu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Jarvis-HEP-Sampler
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Plug-in SDK for user-defined Jarvis-HEP samplers
|
|
5
|
+
Author: Pengxuan Zhu
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Pengxuan-Zhu-Phys/Jarvis-HEP-Sampler
|
|
8
|
+
Project-URL: Repository, https://github.com/Pengxuan-Zhu-Phys/Jarvis-HEP-Sampler
|
|
9
|
+
Project-URL: Issues, https://github.com/Pengxuan-Zhu-Phys/Jarvis-HEP-Sampler/issues
|
|
10
|
+
Keywords: HEP,physics,sampling,Jarvis-HEP,plugin
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: numpy>=1.24
|
|
23
|
+
Requires-Dist: jsonschema>=4.18
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# Jarvis-HEP-Sampler
|
|
27
|
+
|
|
28
|
+
Jarvis-HEP-Sampler is the plug-in SDK for user-defined samplers in the Jarvis ecosystem.
|
|
29
|
+
|
|
30
|
+
A user writes a sampler as one Python file, loads it once, and from then on uses it in a task card exactly like a built-in method. No Jarvis-HEP source code is changed. The plug-in's points go through the same Redis queue, logging and monitor as built-in samplers. The sampler-enabled HEP branch binds each scan to an exact source snapshot and checks scientific settings before resume. Project packages include the source and its full hash; fetch verifies it and prints a load command.
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
Jarvis sampler init MyLatinHypercube # fixed template -> ./MyLatinHypercube.py
|
|
34
|
+
# edit draw() (and optionally OPTIONS_SCHEMA)
|
|
35
|
+
Jarvis sampler check MyLatinHypercube.py # optional offline check, no Redis
|
|
36
|
+
Jarvis sampler load MyLatinHypercube.py # snapshot into ~/.jarvis/samplers; reloading replaces it
|
|
37
|
+
Jarvis run task.yaml # Sampling.Method: MyLatinHypercube
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The `Jarvis sampler` commands are part of Jarvis-HEP and use this package. They are available in the sampler-enabled Jarvis-HEP development branch. The SDK also supports offline Python use (see [Python API](#python-api)).
|
|
41
|
+
|
|
42
|
+
## Scope
|
|
43
|
+
|
|
44
|
+
Jarvis-HEP-Sampler owns the plug-in format:
|
|
45
|
+
|
|
46
|
+
- the fixed template
|
|
47
|
+
- the `PLUGIN` metadata rules and method-name rule
|
|
48
|
+
- loading a plug-in file
|
|
49
|
+
- the user registry in `~/.jarvis/samplers/`
|
|
50
|
+
- the deterministic random streams
|
|
51
|
+
- the output contract (shape, real, finite, inside `[0, 1]`)
|
|
52
|
+
- the `log` facade handed to plug-ins
|
|
53
|
+
- the offline driver and conformance checks
|
|
54
|
+
|
|
55
|
+
Jarvis-HEP owns the runtime:
|
|
56
|
+
|
|
57
|
+
- the `Jarvis sampler` CLI
|
|
58
|
+
- task-card validation
|
|
59
|
+
- the run preflight
|
|
60
|
+
- mapping unit-cube points to physical parameters, and `selection`
|
|
61
|
+
- Sample UUIDs, Redis, Workers and the Archiver
|
|
62
|
+
- checkpoints and resume
|
|
63
|
+
- the sampler log, telemetry and monitor
|
|
64
|
+
- `Jarvis man` and project packing
|
|
65
|
+
|
|
66
|
+
This package never imports Jarvis-HEP, Redis or Portal.
|
|
67
|
+
|
|
68
|
+
## Complete package installation
|
|
69
|
+
|
|
70
|
+
Version 1.0.0. Install from PyPI:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
python -m pip install "Jarvis-HEP-Sampler==1.0.0"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
From this repository:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
python -m pip install .
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Dependencies: NumPy and jsonschema. A sampler-enabled Jarvis-HEP installs this SDK with `Jarvis-HEP-Sampler>=1.0.0,<2`.
|
|
83
|
+
|
|
84
|
+
The end-to-end user tutorial lives in Jarvis-Books, in the TeX manual chapter **Jarvis-HEP-Sampler: Implementing Your Own Sampler** (`TeX/Jarvis-HEP-V2 manual`).
|
|
85
|
+
|
|
86
|
+
## A plug-in
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
"""Latin hypercube design: one point per stratum in every variable."""
|
|
90
|
+
|
|
91
|
+
import numpy as np
|
|
92
|
+
|
|
93
|
+
PLUGIN = {
|
|
94
|
+
"api_version": 1,
|
|
95
|
+
"method": "MyLatinHypercube",
|
|
96
|
+
"version": "0.1.0",
|
|
97
|
+
"profile": "independent",
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
OPTIONS_SCHEMA = { # optional
|
|
101
|
+
"type": "object",
|
|
102
|
+
"properties": {"centered": {"type": "boolean"}},
|
|
103
|
+
"additionalProperties": False,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def prepare(setup):
|
|
108
|
+
rng = setup.rng()
|
|
109
|
+
perms = np.stack([rng.permutation(setup.point_number) for _ in range(setup.dimension)])
|
|
110
|
+
return {"perms": perms, "centered": bool(setup.options.get("centered", False))}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def draw(context, rng, plan):
|
|
114
|
+
strata = plan["perms"][:, context.candidate_index]
|
|
115
|
+
offset = 0.5 if plan["centered"] else rng.random(context.dimension)
|
|
116
|
+
return (strata + offset) / context.point_number
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
Sampling:
|
|
121
|
+
Method: MyLatinHypercube
|
|
122
|
+
Variables:
|
|
123
|
+
- name: mass
|
|
124
|
+
distribution: {type: Flat, parameters: {min: 100.0, max: 1000.0}}
|
|
125
|
+
Bounds:
|
|
126
|
+
seed: 7
|
|
127
|
+
point_number: 10000
|
|
128
|
+
centered: false
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The full contract is in [Plug-in authoring](docs/development/PLUGIN_AUTHORING.md).
|
|
132
|
+
|
|
133
|
+
A complete runnable card is provided in
|
|
134
|
+
[examples/MyLatinHypercube.task.yaml](examples/MyLatinHypercube.task.yaml).
|
|
135
|
+
It uses Jarvis-HEP's bundled Eggbox demonstration operator:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
Jarvis sampler check examples/MyLatinHypercube.py --card examples/MyLatinHypercube.task.yaml
|
|
139
|
+
Jarvis sampler load examples/MyLatinHypercube.py
|
|
140
|
+
Jarvis validate examples/MyLatinHypercube.task.yaml
|
|
141
|
+
Jarvis check examples/MyLatinHypercube.task.yaml
|
|
142
|
+
Jarvis run examples/MyLatinHypercube.task.yaml
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`Jarvis sampler check` is the offline file check and does not require `load`. `Jarvis check` is the calculator smoke: its identity, bound source and checkpoint stay under `DATABASE/test` and `checkpoints/<scan>/<Method>/check/`, and the formal scan's science database and resume checkpoint stay in place.
|
|
146
|
+
|
|
147
|
+
Reloading the same method updates future scans. Removing the registration
|
|
148
|
+
preserves an existing scan's bound source and its normal `Jarvis run ... --resume`
|
|
149
|
+
workflow.
|
|
150
|
+
|
|
151
|
+
## Python API
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from jarvis_hep_sampler import SamplerRegistry, write_template
|
|
155
|
+
from jarvis_hep_sampler.testing import check_plugin, run_offline
|
|
156
|
+
|
|
157
|
+
path = write_template("MyLatinHypercube") # Jarvis sampler init
|
|
158
|
+
report = check_plugin(path, dimension=2, options={}) # Jarvis sampler check
|
|
159
|
+
for name, result in report.rows():
|
|
160
|
+
print(f"{name:14} {result}")
|
|
161
|
+
|
|
162
|
+
run = run_offline(path, variable_names=["mass", "coupling"], point_number=1000, seed=7)
|
|
163
|
+
print(run.points.shape, run.stop_reason)
|
|
164
|
+
|
|
165
|
+
SamplerRegistry().load(path) # Jarvis sampler load
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Documentation
|
|
169
|
+
|
|
170
|
+
- [Plug-in authoring](docs/development/PLUGIN_AUTHORING.md)
|
|
171
|
+
|
|
172
|
+
## Status
|
|
173
|
+
|
|
174
|
+
Alpha. API version 1 supports the independent execution contract; generational metadata reserves a future profile, whose running state/feedback contract remains under design. This release runs `independent` plug-ins; `generational` (feedback samplers) arrives in a later release.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
MIT. See [LICENSE](LICENSE). Copyright (c) 2026 Pengxuan Zhu.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Jarvis-HEP-Sampler
|
|
2
|
+
|
|
3
|
+
Jarvis-HEP-Sampler is the plug-in SDK for user-defined samplers in the Jarvis ecosystem.
|
|
4
|
+
|
|
5
|
+
A user writes a sampler as one Python file, loads it once, and from then on uses it in a task card exactly like a built-in method. No Jarvis-HEP source code is changed. The plug-in's points go through the same Redis queue, logging and monitor as built-in samplers. The sampler-enabled HEP branch binds each scan to an exact source snapshot and checks scientific settings before resume. Project packages include the source and its full hash; fetch verifies it and prints a load command.
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
Jarvis sampler init MyLatinHypercube # fixed template -> ./MyLatinHypercube.py
|
|
9
|
+
# edit draw() (and optionally OPTIONS_SCHEMA)
|
|
10
|
+
Jarvis sampler check MyLatinHypercube.py # optional offline check, no Redis
|
|
11
|
+
Jarvis sampler load MyLatinHypercube.py # snapshot into ~/.jarvis/samplers; reloading replaces it
|
|
12
|
+
Jarvis run task.yaml # Sampling.Method: MyLatinHypercube
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The `Jarvis sampler` commands are part of Jarvis-HEP and use this package. They are available in the sampler-enabled Jarvis-HEP development branch. The SDK also supports offline Python use (see [Python API](#python-api)).
|
|
16
|
+
|
|
17
|
+
## Scope
|
|
18
|
+
|
|
19
|
+
Jarvis-HEP-Sampler owns the plug-in format:
|
|
20
|
+
|
|
21
|
+
- the fixed template
|
|
22
|
+
- the `PLUGIN` metadata rules and method-name rule
|
|
23
|
+
- loading a plug-in file
|
|
24
|
+
- the user registry in `~/.jarvis/samplers/`
|
|
25
|
+
- the deterministic random streams
|
|
26
|
+
- the output contract (shape, real, finite, inside `[0, 1]`)
|
|
27
|
+
- the `log` facade handed to plug-ins
|
|
28
|
+
- the offline driver and conformance checks
|
|
29
|
+
|
|
30
|
+
Jarvis-HEP owns the runtime:
|
|
31
|
+
|
|
32
|
+
- the `Jarvis sampler` CLI
|
|
33
|
+
- task-card validation
|
|
34
|
+
- the run preflight
|
|
35
|
+
- mapping unit-cube points to physical parameters, and `selection`
|
|
36
|
+
- Sample UUIDs, Redis, Workers and the Archiver
|
|
37
|
+
- checkpoints and resume
|
|
38
|
+
- the sampler log, telemetry and monitor
|
|
39
|
+
- `Jarvis man` and project packing
|
|
40
|
+
|
|
41
|
+
This package never imports Jarvis-HEP, Redis or Portal.
|
|
42
|
+
|
|
43
|
+
## Complete package installation
|
|
44
|
+
|
|
45
|
+
Version 1.0.0. Install from PyPI:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
python -m pip install "Jarvis-HEP-Sampler==1.0.0"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
From this repository:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
python -m pip install .
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Dependencies: NumPy and jsonschema. A sampler-enabled Jarvis-HEP installs this SDK with `Jarvis-HEP-Sampler>=1.0.0,<2`.
|
|
58
|
+
|
|
59
|
+
The end-to-end user tutorial lives in Jarvis-Books, in the TeX manual chapter **Jarvis-HEP-Sampler: Implementing Your Own Sampler** (`TeX/Jarvis-HEP-V2 manual`).
|
|
60
|
+
|
|
61
|
+
## A plug-in
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
"""Latin hypercube design: one point per stratum in every variable."""
|
|
65
|
+
|
|
66
|
+
import numpy as np
|
|
67
|
+
|
|
68
|
+
PLUGIN = {
|
|
69
|
+
"api_version": 1,
|
|
70
|
+
"method": "MyLatinHypercube",
|
|
71
|
+
"version": "0.1.0",
|
|
72
|
+
"profile": "independent",
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
OPTIONS_SCHEMA = { # optional
|
|
76
|
+
"type": "object",
|
|
77
|
+
"properties": {"centered": {"type": "boolean"}},
|
|
78
|
+
"additionalProperties": False,
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def prepare(setup):
|
|
83
|
+
rng = setup.rng()
|
|
84
|
+
perms = np.stack([rng.permutation(setup.point_number) for _ in range(setup.dimension)])
|
|
85
|
+
return {"perms": perms, "centered": bool(setup.options.get("centered", False))}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def draw(context, rng, plan):
|
|
89
|
+
strata = plan["perms"][:, context.candidate_index]
|
|
90
|
+
offset = 0.5 if plan["centered"] else rng.random(context.dimension)
|
|
91
|
+
return (strata + offset) / context.point_number
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
Sampling:
|
|
96
|
+
Method: MyLatinHypercube
|
|
97
|
+
Variables:
|
|
98
|
+
- name: mass
|
|
99
|
+
distribution: {type: Flat, parameters: {min: 100.0, max: 1000.0}}
|
|
100
|
+
Bounds:
|
|
101
|
+
seed: 7
|
|
102
|
+
point_number: 10000
|
|
103
|
+
centered: false
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The full contract is in [Plug-in authoring](docs/development/PLUGIN_AUTHORING.md).
|
|
107
|
+
|
|
108
|
+
A complete runnable card is provided in
|
|
109
|
+
[examples/MyLatinHypercube.task.yaml](examples/MyLatinHypercube.task.yaml).
|
|
110
|
+
It uses Jarvis-HEP's bundled Eggbox demonstration operator:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
Jarvis sampler check examples/MyLatinHypercube.py --card examples/MyLatinHypercube.task.yaml
|
|
114
|
+
Jarvis sampler load examples/MyLatinHypercube.py
|
|
115
|
+
Jarvis validate examples/MyLatinHypercube.task.yaml
|
|
116
|
+
Jarvis check examples/MyLatinHypercube.task.yaml
|
|
117
|
+
Jarvis run examples/MyLatinHypercube.task.yaml
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`Jarvis sampler check` is the offline file check and does not require `load`. `Jarvis check` is the calculator smoke: its identity, bound source and checkpoint stay under `DATABASE/test` and `checkpoints/<scan>/<Method>/check/`, and the formal scan's science database and resume checkpoint stay in place.
|
|
121
|
+
|
|
122
|
+
Reloading the same method updates future scans. Removing the registration
|
|
123
|
+
preserves an existing scan's bound source and its normal `Jarvis run ... --resume`
|
|
124
|
+
workflow.
|
|
125
|
+
|
|
126
|
+
## Python API
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from jarvis_hep_sampler import SamplerRegistry, write_template
|
|
130
|
+
from jarvis_hep_sampler.testing import check_plugin, run_offline
|
|
131
|
+
|
|
132
|
+
path = write_template("MyLatinHypercube") # Jarvis sampler init
|
|
133
|
+
report = check_plugin(path, dimension=2, options={}) # Jarvis sampler check
|
|
134
|
+
for name, result in report.rows():
|
|
135
|
+
print(f"{name:14} {result}")
|
|
136
|
+
|
|
137
|
+
run = run_offline(path, variable_names=["mass", "coupling"], point_number=1000, seed=7)
|
|
138
|
+
print(run.points.shape, run.stop_reason)
|
|
139
|
+
|
|
140
|
+
SamplerRegistry().load(path) # Jarvis sampler load
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Documentation
|
|
144
|
+
|
|
145
|
+
- [Plug-in authoring](docs/development/PLUGIN_AUTHORING.md)
|
|
146
|
+
|
|
147
|
+
## Status
|
|
148
|
+
|
|
149
|
+
Alpha. API version 1 supports the independent execution contract; generational metadata reserves a future profile, whose running state/feedback contract remains under design. This release runs `independent` plug-ins; `generational` (feedback samplers) arrives in a later release.
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT. See [LICENSE](LICENSE). Copyright (c) 2026 Pengxuan Zhu.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Plug-in authoring
|
|
2
|
+
|
|
3
|
+
A sampler plug-in is one `.py` file. Start from the template (`Jarvis sampler init <Name>`), edit it, load it (`Jarvis sampler load <file>`), then write `Sampling.Method: <Name>` in a task card.
|
|
4
|
+
|
|
5
|
+
The plug-in only produces points in the unit cube. Jarvis-HEP maps them through `Variables` and `Mapper`, applies `selection`, and runs them through Workers. You never touch Sample objects, UUIDs, Redis or the DATABASE.
|
|
6
|
+
|
|
7
|
+
## File contents
|
|
8
|
+
|
|
9
|
+
| Name | Required | Purpose |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `PLUGIN` | yes | Metadata dict, JSON data only (below) |
|
|
12
|
+
| `OPTIONS_SCHEMA` | no | JSON Schema (draft 2020-12) for your Bounds options. Leave it out, or set it to `None`, and your options are not checked |
|
|
13
|
+
| `prepare(setup)` | no | Runs once per scan, and again on resume. Returns the `plan` passed to `draw` |
|
|
14
|
+
| `draw(context, rng, plan)` | yes, unless you use blocks | Returns one point |
|
|
15
|
+
| `draw_block(context, rng, plan)` | with `block_size` | Returns `block_size` points at once |
|
|
16
|
+
| `validate_options(options)` | no | Raise to reject options, beyond what the schema checks |
|
|
17
|
+
| `settings_rows(setup, plan)` | no | Extra rows for the settings table |
|
|
18
|
+
| `summary_rows(plan, stats)` | no | Extra rows for the summary table |
|
|
19
|
+
| `stop_reason(plan, stats)` | no | Stop reason for the summary |
|
|
20
|
+
| `status(plan, stats)` | no | Metrics for the monitor |
|
|
21
|
+
|
|
22
|
+
You may import any library installed in your environment. Missing imports fail at `load`, at `check`, or when the run starts.
|
|
23
|
+
|
|
24
|
+
## `PLUGIN`
|
|
25
|
+
|
|
26
|
+
| Key | Required | Value |
|
|
27
|
+
| --- | --- | --- |
|
|
28
|
+
| `api_version` | yes | `1` |
|
|
29
|
+
| `method` | yes | The `Sampling.Method` name. It must look like a built-in name: an upper-case letter, then 1–63 letters or digits (`MyLatinHypercube`). It cannot be a built-in name, in any letter case |
|
|
30
|
+
| `version` | yes | Your version string. Change it whenever the algorithm changes meaning. HEP checks saved version/configuration on resume; start a new scan after science changes |
|
|
31
|
+
| `profile` | yes | `"independent"`. `"generational"` is reserved for feedback samplers in a later release |
|
|
32
|
+
| `description` | no | One line, shown by `Jarvis man` and `Jarvis sampler list` |
|
|
33
|
+
| `statistical` | no | `True` turns on the same Mapper warnings as the statistical built-in methods. It does not make your points posterior samples |
|
|
34
|
+
| `block_size` | no | Use `draw_block` with blocks of this size instead of `draw` |
|
|
35
|
+
|
|
36
|
+
Unknown keys are an error, so a typo cannot pass silently.
|
|
37
|
+
|
|
38
|
+
## Bounds: reserved keys and your options
|
|
39
|
+
|
|
40
|
+
| Key | Owner | Rule |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| `seed` | Jarvis-HEP | Non-negative integer, default `0` |
|
|
43
|
+
| `point_number` | Jarvis-HEP | Positive integer, required. The number of candidates; points rejected by `selection` count |
|
|
44
|
+
| `max_worker` | Jarvis-HEP | Run-time in-flight limit |
|
|
45
|
+
| everything else | you | Your options, available as `setup.options` / `context.options` |
|
|
46
|
+
|
|
47
|
+
Options must be JSON data (strings, numbers, booleans, null, lists, mappings). Inside the plug-in they are read-only: lists arrive as tuples and mappings cannot be changed. Schema `default` values are not filled in; use `options.get("key", default)`.
|
|
48
|
+
|
|
49
|
+
## Contexts
|
|
50
|
+
|
|
51
|
+
| Field | `setup` | `context` (draw) | `context` (draw_block) |
|
|
52
|
+
| --- | --- | --- | --- |
|
|
53
|
+
| `seed` | ✓ | | |
|
|
54
|
+
| `point_number`, `dimension`, `variable_names`, `options`, `log` | ✓ | ✓ | ✓ |
|
|
55
|
+
| `rng()` | ✓, a generator reserved for `prepare` | | |
|
|
56
|
+
| `candidate_index` | | ✓ | |
|
|
57
|
+
| `block_index`, `block_size` | | | ✓ |
|
|
58
|
+
|
|
59
|
+
`variable_names` follows the order of `Variables` in the task card, and `dimension` is its length.
|
|
60
|
+
|
|
61
|
+
## Points
|
|
62
|
+
|
|
63
|
+
- `draw` returns a 1-D array, list or tuple of length `dimension`.
|
|
64
|
+
- `draw_block` returns shape `(block_size, dimension)` for candidates `[block_index * block_size, (block_index + 1) * block_size)`. Rows past `point_number` are dropped.
|
|
65
|
+
- Values must be real numbers (not bool, complex or strings), finite, with `0 <= u <= 1`.
|
|
66
|
+
- After mapping, every physical value must also be finite. Jarvis-HEP checks this.
|
|
67
|
+
|
|
68
|
+
A bad point stops the scan with the candidate index and the component. Nothing is clipped or redrawn for you.
|
|
69
|
+
|
|
70
|
+
## Randomness and resume
|
|
71
|
+
|
|
72
|
+
Use the `rng` you are given; do not use `np.random.*` global functions, time or process IDs.
|
|
73
|
+
|
|
74
|
+
- `draw` gets a generator that depends only on `(seed, candidate_index)`.
|
|
75
|
+
- `draw_block` gets one that depends only on `(seed, block_index)`.
|
|
76
|
+
- `prepare` uses `setup.rng()`.
|
|
77
|
+
|
|
78
|
+
For a deterministic plan, points are the same whatever the number of Workers, batch size or completion order. Replaying the same source and configuration reproduces the indexed stream within the same environment; the sampler-enabled HEP branch checks configuration, checkpoint identity and the full bound source hash before recovery. Reloading or removing the user registration does not change an existing scan.
|
|
79
|
+
|
|
80
|
+
`prepare` runs again on resume, so the plan must follow from `setup` alone. Module-level state is allowed but outside this guarantee. `Jarvis sampler check` catches the common case of drawing from an unseeded global generator.
|
|
81
|
+
|
|
82
|
+
## Logging and monitor
|
|
83
|
+
|
|
84
|
+
Every context has `log`. Jarvis-HEP writes the start, settings, ready, checkpoint, failure, result and summary records itself. Use `log` for the rest:
|
|
85
|
+
|
|
86
|
+
| Call | Record |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| `log.step(title, rows)` | A table per stage or generation (INFO) |
|
|
89
|
+
| `log.adjust(name, old, new, why)` | A setting you changed, ignored or clamped (WARNING) |
|
|
90
|
+
| `log.saved(what, path)` | `<What> saved to <path>` for a file you wrote (WARNING) |
|
|
91
|
+
| `log.info(...)`, `log.warning(...)`, `log.debug(...)` | Anything else |
|
|
92
|
+
|
|
93
|
+
`stats` in the hooks has `candidates`, `accepted` and `point_number`. `status` may return up to 8 scalar metrics, with strings of up to 32 characters; NumPy boolean, integer, floating-point and string scalars are converted to their Python equivalents. Extra, non-finite or non-scalar entries are dropped. A reporting hook that raises, including while its returned rows or mapping are consumed or converted, is logged and skipped; it never stops the scan. Interrupts and process-exit requests still propagate. Without `stop_reason`, the reason is `point_number reached`.
|
|
94
|
+
|
|
95
|
+
## Errors
|
|
96
|
+
|
|
97
|
+
| Error | When |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| `PluginLoadError` | The file does not import, `PLUGIN` is invalid, a required function is missing, or the name is taken |
|
|
100
|
+
| `PluginConfigError` | Options break the schema, or `validate_options` / `prepare` raised |
|
|
101
|
+
| `PluginOutputError` | `draw` / `draw_block` raised or returned a bad point |
|
|
102
|
+
| `PluginResumeMismatch` | A resumed scan does not match the original run |
|
|
103
|
+
| `RegistryError` | `~/.jarvis/samplers` is unreadable or a snapshot is broken |
|
|
104
|
+
|
|
105
|
+
Your own exception is chained to these, so its traceback reaches the log. Output conversion errors, including overflow when converting to float64, are also reported as `PluginOutputError` with the method and candidate position. A failing draw stops the scan; Jarvis-HEP never falls back to another sampler.
|
|
106
|
+
|
|
107
|
+
## The registry
|
|
108
|
+
|
|
109
|
+
`Jarvis sampler load` copies the file to `~/.jarvis/samplers/user_sources/<Method>-<hash>.py` and records it in `~/.jarvis/samplers/sources.json`. `JARVIS_SAMPLERS_HOME` moves that directory.
|
|
110
|
+
|
|
111
|
+
- Runs use the copy, not your working file. Edit, then load again.
|
|
112
|
+
- `Jarvis sampler list` marks a working file changed since the last load.
|
|
113
|
+
- Loading the same method again replaces the entry and retires the old copy.
|
|
114
|
+
- If removing a retired copy fails after the registration commits, the command
|
|
115
|
+
still succeeds and reports a cleanup warning. Only explicitly retired copies
|
|
116
|
+
are retried on a later successful load/remove; arbitrary files are not swept.
|
|
117
|
+
- The SDK retains a private `.pending_cleanup.json` only when cleanup needs a
|
|
118
|
+
retry. A damaged retry file or a failure to save it is reported without
|
|
119
|
+
undoing the completed registration; manual cleanup may then be needed.
|
|
120
|
+
|
|
121
|
+
The SDK reads and verifies snapshot bytes under the registry lock, then imports
|
|
122
|
+
those same bytes after releasing the lock. Managed snapshot paths must stay
|
|
123
|
+
inside `user_sources` and cannot be symbolic links. Removing a registration
|
|
124
|
+
preserves the working source file and an existing scan's own bound source.
|
|
125
|
+
|
|
126
|
+
The registry belongs to your user account on one machine. Load the plug-in on every machine that runs the card.
|
|
127
|
+
|
|
128
|
+
## Operational limits
|
|
129
|
+
|
|
130
|
+
A snapshot fixes only this Python entry file. Install any packages it imports in the same environment as Jarvis-HEP. Sibling modules and data files are not copied, and `__file__` points at the snapshot during a real run. The independent profile does not use Worker feedback; points may still be correlated, as in LHS or a low-discrepancy design.
|
|
131
|
+
|
|
132
|
+
`Jarvis sampler check` executes the file, reimports the same source bytes, and restarts them in a fresh Python process to compare the tail. A successful check exercises this configuration; it does not prove the algorithm scientifically correct. `--card` preserves the card budget unless `--points` explicitly overrides it; this override changes the total design, rather than just the number of checked points.
|
|
133
|
+
|
|
134
|
+
`Jarvis check` is the separate calculator smoke. It draws a few points through the loaded plug-in and the card's opera and likelihood. Its identity goes to `DATABASE/test/sampler_identity.json`, and its bound source and checkpoint go under `checkpoints/<scan>/<Method>/check/`. It does not read or replace the formal science database, bound source or resume checkpoint. `runtime.json`, logs and `run_summary` stay in the scan's ordinary files.
|
|
135
|
+
|
|
136
|
+
Schemas are optional. When supplied, local `$defs`/`$ref` references are supported. Referenced documents are never downloaded during validation; unresolved references produce an offline diagnostic. Schema defaults remain documentation and are not applied automatically.
|
|
137
|
+
|
|
138
|
+
Reporting hooks are optional. Jarvis-HEP logs explicit options without them, with bounded display (32 rows, 256 characters per cell); a hook can show defaults or derived values. `status` runs on the sampling thread and is cached for monitor/heartbeat readers. Keep it quick and read-only with respect to `plan`; repeated errors are logged once per hook per session, with bounded error retention. A hanging user function has no enforced timeout.
|
|
139
|
+
|
|
140
|
+
Default strict resume and project source packing are implemented in the sampler-enabled HEP branch. Changing source during an existing scan, promotion to other built-in methods, and feedback/generational execution remain later milestones. Cross-version numerical identity is not promised; changed SDK/Python/NumPy versions produce a warning. The complete user workflow is documented in the Jarvis-Books TeX manual chapter **Jarvis-HEP-Sampler: Implementing Your Own Sampler**.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Latin hypercube design: one point per stratum in every variable.
|
|
2
|
+
|
|
3
|
+
Load it with ``Jarvis sampler load examples/MyLatinHypercube.py`` and write
|
|
4
|
+
``Sampling.Method: MyLatinHypercube`` in a task card.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
PLUGIN = {
|
|
10
|
+
"api_version": 1,
|
|
11
|
+
"method": "MyLatinHypercube",
|
|
12
|
+
"version": "0.1.0",
|
|
13
|
+
"profile": "independent",
|
|
14
|
+
"description": "Latin hypercube design with point_number strata per variable.",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
OPTIONS_SCHEMA = {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"properties": {
|
|
20
|
+
"centered": {
|
|
21
|
+
"type": "boolean",
|
|
22
|
+
"description": "Put each point at the centre of its stratum.",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
"additionalProperties": False,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def prepare(setup):
|
|
30
|
+
rng = setup.rng()
|
|
31
|
+
perms = np.stack([rng.permutation(setup.point_number) for _ in range(setup.dimension)])
|
|
32
|
+
return {"perms": perms, "centered": bool(setup.options.get("centered", False))}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def draw(context, rng, plan):
|
|
36
|
+
strata = plan["perms"][:, context.candidate_index]
|
|
37
|
+
offset = 0.5 if plan["centered"] else rng.random(context.dimension)
|
|
38
|
+
return (strata + offset) / context.point_number
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def settings_rows(setup, plan):
|
|
42
|
+
return [("centered", plan["centered"])]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Complete native Jarvis-HEP demo card; load MyLatinHypercube.py first.
|
|
2
|
+
Scan:
|
|
3
|
+
name: sampler-lhs-demo
|
|
4
|
+
EnvReqs:
|
|
5
|
+
V2:
|
|
6
|
+
workers: 2
|
|
7
|
+
batch_size: 4
|
|
8
|
+
Sampling:
|
|
9
|
+
Method: MyLatinHypercube
|
|
10
|
+
Bounds:
|
|
11
|
+
seed: 7
|
|
12
|
+
point_number: 32
|
|
13
|
+
centered: true
|
|
14
|
+
Variables:
|
|
15
|
+
- name: x
|
|
16
|
+
distribution:
|
|
17
|
+
type: Flat
|
|
18
|
+
parameters: {min: 0.0, max: 1.0}
|
|
19
|
+
- name: y
|
|
20
|
+
distribution:
|
|
21
|
+
type: Flat
|
|
22
|
+
parameters: {min: 0.0, max: 1.0}
|
|
23
|
+
LogLikelihood:
|
|
24
|
+
- name: LogL_Z
|
|
25
|
+
expression: z
|
|
26
|
+
Operas:
|
|
27
|
+
Modules:
|
|
28
|
+
- name: DemoEggbox
|
|
29
|
+
operator: jarvishep2.testing.eggbox.eggbox2d_numpy
|
|
30
|
+
input:
|
|
31
|
+
- {name: x, expression: x}
|
|
32
|
+
- {name: y, expression: y}
|
|
33
|
+
output:
|
|
34
|
+
- {name: z, entry: z}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "Jarvis-HEP-Sampler"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Plug-in SDK for user-defined Jarvis-HEP samplers"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Pengxuan Zhu" }
|
|
14
|
+
]
|
|
15
|
+
keywords = ["HEP", "physics", "sampling", "Jarvis-HEP", "plugin"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"numpy>=1.24",
|
|
28
|
+
"jsonschema>=4.18",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/Pengxuan-Zhu-Phys/Jarvis-HEP-Sampler"
|
|
34
|
+
Repository = "https://github.com/Pengxuan-Zhu-Phys/Jarvis-HEP-Sampler"
|
|
35
|
+
Issues = "https://github.com/Pengxuan-Zhu-Phys/Jarvis-HEP-Sampler/issues"
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["src"]
|
|
39
|
+
include = ["jarvis_hep_sampler*"]
|
|
40
|
+
|
|
41
|
+
[tool.setuptools.package-data]
|
|
42
|
+
jarvis_hep_sampler = ["py.typed", "templates/*.tmpl"]
|
|
43
|
+
|
|
44
|
+
[tool.pytest.ini_options]
|
|
45
|
+
testpaths = ["tests"]
|
|
46
|
+
|
|
47
|
+
[tool.ruff]
|
|
48
|
+
line-length = 100
|
|
49
|
+
target-version = "py310"
|
|
50
|
+
|
|
51
|
+
[tool.ruff.lint]
|
|
52
|
+
select = ["E", "F", "I", "UP", "B"]
|