beam-infer 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.
- beam_infer-1.0.0/LICENSE +24 -0
- beam_infer-1.0.0/PKG-INFO +364 -0
- beam_infer-1.0.0/README.md +328 -0
- beam_infer-1.0.0/beam_infer/__init__.py +72 -0
- beam_infer-1.0.0/beam_infer/base_model.py +144 -0
- beam_infer-1.0.0/beam_infer/mcmc/mcmc_interface.py +474 -0
- beam_infer-1.0.0/beam_infer/mcmc/parallel_tempering.py +418 -0
- beam_infer-1.0.0/beam_infer/minimization/engine.py +521 -0
- beam_infer-1.0.0/beam_infer/minimization/minimization_interface.py +333 -0
- beam_infer-1.0.0/beam_infer/minimization/optimizer_interface.py +357 -0
- beam_infer-1.0.0/beam_infer/utils.py +67 -0
- beam_infer-1.0.0/beam_infer.egg-info/PKG-INFO +364 -0
- beam_infer-1.0.0/beam_infer.egg-info/SOURCES.txt +16 -0
- beam_infer-1.0.0/beam_infer.egg-info/dependency_links.txt +1 -0
- beam_infer-1.0.0/beam_infer.egg-info/requires.txt +16 -0
- beam_infer-1.0.0/beam_infer.egg-info/top_level.txt +1 -0
- beam_infer-1.0.0/pyproject.toml +79 -0
- beam_infer-1.0.0/setup.cfg +4 -0
beam_infer-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Joel Henriksson, Hugo Valim
|
|
4
|
+
|
|
5
|
+
Original work by Joel Henriksson (Lund University, LTH)
|
|
6
|
+
Package integration by Hugo Valim (ESS)
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
in the Software without restriction, including without limitation the rights
|
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
SOFTWARE.
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: beam-infer
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A Python package for beam simulation and parameter inference using raster scanning models
|
|
5
|
+
Author-email: Joel Henriksson <carljoelhenriksson@gmail.com>, Hugo Valim <hugo.valim@ess.eu>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Original_Work, https://github.com/juhelh/ess-beam-imaging-inverse-problems
|
|
8
|
+
Keywords: beam,simulation,raster,mcmc,inference,optimization,fitting
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: numpy>=1.20.0
|
|
22
|
+
Requires-Dist: jax>=0.4.0
|
|
23
|
+
Requires-Dist: jaxlib>=0.4.0
|
|
24
|
+
Requires-Dist: scipy>=1.7.0
|
|
25
|
+
Provides-Extra: gpu
|
|
26
|
+
Requires-Dist: jax[cuda12]>=0.4.0; extra == "gpu"
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: matplotlib>=3.5.0; extra == "dev"
|
|
31
|
+
Requires-Dist: tqdm>=4.60.0; extra == "dev"
|
|
32
|
+
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: flake8>=5.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# Beam-Infer
|
|
38
|
+
|
|
39
|
+
**Beam-Infer** is a Python library for beam parameter inference from raster-scanned images. It provides three high-level wrappers for parameter estimation using optimization and MCMC methods, with full control over configuration while maintaining a simple, stable API.
|
|
40
|
+
|
|
41
|
+
> **Note:** This package is based on the original work by **Joel Henriksson** (Lund University, LTH) from his master's thesis *"Inverse Problems in Proton Beam Imaging at ESS: Analysis and Numerical Methods"*. The core calculation base and algorithms were implemented by Joel Henriksson. This package integrates that work into ESS systems.
|
|
42
|
+
>
|
|
43
|
+
> **Original Repository:** [ess-beam-imaging-inverse-problems](https://github.com/juhelh/ess-beam-imaging-inverse-problems)
|
|
44
|
+
|
|
45
|
+
**Numerical equivalence** to the legacy base implementation (forward model, loss, optimizer pipeline, Poisson MCMC) is tested and documented; see [docs/EQUIVALENCE.md](docs/EQUIVALENCE.md). This package focuses on the calculation layer only; EPICS integration and I/O are handled elsewhere.
|
|
46
|
+
|
|
47
|
+
## Features
|
|
48
|
+
|
|
49
|
+
- **Complete Pipeline**: `estimate_with_optimizer` handles preprocessing, grid construction, initialization, and optimization
|
|
50
|
+
- **Multistart Optimization**: `run_multistart_minimization` for robust parameter recovery
|
|
51
|
+
- **MCMC Sampling**: `run_mcmc_inference` for Bayesian parameter estimation with uncertainty quantification
|
|
52
|
+
- **Flexible Configuration**: Rich configuration via dataclasses for all inference methods
|
|
53
|
+
- **JAX-based**: Fast, GPU-accelerated computations using JAX
|
|
54
|
+
- **Reproducible**: Optional random seeds for deterministic multistart runs
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
### From Source
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://gitlab.esss.lu.se/hugovalim/beam-infer.git
|
|
62
|
+
cd beam-infer
|
|
63
|
+
pip install -e .
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Development Installation
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install -e ".[dev]"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Quick Start
|
|
73
|
+
|
|
74
|
+
### Full Pipeline (Recommended)
|
|
75
|
+
|
|
76
|
+
The `estimate_with_optimizer` function provides a complete pipeline from raw camera image to estimated parameters:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
import numpy as np
|
|
80
|
+
import beam_infer
|
|
81
|
+
|
|
82
|
+
# Raw camera image (2D numpy array)
|
|
83
|
+
raw_image = np.array(...) # Your image data
|
|
84
|
+
|
|
85
|
+
# Metadata (known quantities)
|
|
86
|
+
meta = beam_infer.Metadata(
|
|
87
|
+
pulse_duration_ms=0.05, # Pulse duration in milliseconds
|
|
88
|
+
fx=39.55, # Horizontal scan frequency (kHz) - optional, fixes if provided
|
|
89
|
+
fy=29.05, # Vertical scan frequency (kHz) - optional, fixes if provided
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Configuration
|
|
93
|
+
config = beam_infer.OptimizerConfig(
|
|
94
|
+
max_iterations=100, # Maximum L-BFGS-B iterations per run
|
|
95
|
+
multistart={"n_starts": 5, "type": "uniform"}, # Multistart configuration
|
|
96
|
+
regularization={"params": {"sigx": 0.1, "sigy": 0.1}}, # Optional regularization
|
|
97
|
+
random_seed=42, # Optional: for reproducible multistart runs
|
|
98
|
+
verbose=False, # Print iteration details
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Run estimation
|
|
102
|
+
result = beam_infer.estimate_with_optimizer(raw_image, meta=meta, config=config)
|
|
103
|
+
|
|
104
|
+
# Access results
|
|
105
|
+
print(f"Estimated parameters: {result.estimated_parameters}")
|
|
106
|
+
print(f"Final loss: {result.objective_value:.6e}")
|
|
107
|
+
print(f"Success: {result.success}")
|
|
108
|
+
print(f"Crop bounds: {result.crop_bounds}")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Multistart Minimization
|
|
112
|
+
|
|
113
|
+
For more control over the optimization process:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
import numpy as np
|
|
117
|
+
import jax.numpy as jnp
|
|
118
|
+
import beam_infer
|
|
119
|
+
|
|
120
|
+
# Preprocessed image and grids (you handle preprocessing)
|
|
121
|
+
observed_image = np.array(...) # Already preprocessed
|
|
122
|
+
X, Y = ... # 2D coordinate grids matching image shape
|
|
123
|
+
t_vals = ... # 1D time array
|
|
124
|
+
|
|
125
|
+
# Initial guess (10 parameters)
|
|
126
|
+
k0 = jnp.array([60.0, 20.0, 13.5, 5.05, 0.0, 0.0, 39.55, 29.05, 0.0, 0.0])
|
|
127
|
+
|
|
128
|
+
# Bounds (optional)
|
|
129
|
+
lower = jnp.array([0.0, 0.0, 2.0, 2.0, -20.0, -20.0, 20.0, 20.0, -np.pi, -np.pi])
|
|
130
|
+
upper = jnp.array([100.0, 50.0, 20.0, 20.0, 20.0, 20.0, 50.0, 50.0, np.pi, np.pi])
|
|
131
|
+
|
|
132
|
+
# Configuration
|
|
133
|
+
config = beam_infer.MinimizationConfig(
|
|
134
|
+
initial_guess=k0,
|
|
135
|
+
bounds=(lower, upper),
|
|
136
|
+
max_iterations=100,
|
|
137
|
+
verbose=False,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# Run multistart optimization
|
|
141
|
+
result = beam_infer.run_multistart_minimization(
|
|
142
|
+
observed_image,
|
|
143
|
+
X, Y, t_vals,
|
|
144
|
+
config,
|
|
145
|
+
num_starts=10,
|
|
146
|
+
random_seed=42, # For reproducibility
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# Access best result
|
|
150
|
+
best = result.best_result
|
|
151
|
+
print(f"Best parameters: {best.estimated_parameters}")
|
|
152
|
+
print(f"Best loss: {best.objective_value:.6e}")
|
|
153
|
+
|
|
154
|
+
# Access all results (sorted by loss)
|
|
155
|
+
for i, r in enumerate(result.results):
|
|
156
|
+
print(f"Run {i}: loss = {r.objective_value:.6e}")
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### MCMC Inference
|
|
160
|
+
|
|
161
|
+
For Bayesian parameter estimation with uncertainty quantification:
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
import numpy as np
|
|
165
|
+
import beam_infer
|
|
166
|
+
|
|
167
|
+
# Observed image (counts or normalized intensity)
|
|
168
|
+
observed_image = np.array(...) # 2D image
|
|
169
|
+
X, Y = ... # 2D coordinate grids
|
|
170
|
+
t_vals = ... # 1D time array
|
|
171
|
+
|
|
172
|
+
# Bounds
|
|
173
|
+
lower = np.array([0.0, 0.0, 2.0, 2.0, -20.0, -20.0, 20.0, 20.0, -np.pi, -np.pi])
|
|
174
|
+
upper = np.array([100.0, 50.0, 20.0, 20.0, 20.0, 20.0, 50.0, 50.0, np.pi, np.pi])
|
|
175
|
+
|
|
176
|
+
# MCMC configuration
|
|
177
|
+
config = beam_infer.MCMCConfig(
|
|
178
|
+
lower_bounds=lower,
|
|
179
|
+
upper_bounds=upper,
|
|
180
|
+
num_samples=4000, # Number of samples to collect
|
|
181
|
+
burn_in=1000, # Burn-in period
|
|
182
|
+
thin=2, # Thinning (keep every Nth sample)
|
|
183
|
+
prior_type="uniform", # or "gaussian"
|
|
184
|
+
seed=42, # Random seed
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# Run MCMC
|
|
188
|
+
result = beam_infer.run_mcmc_inference(observed_image, X, Y, t_vals, config)
|
|
189
|
+
|
|
190
|
+
# Access results
|
|
191
|
+
print(f"Posterior mean: {result.posterior_mean}")
|
|
192
|
+
print(f"Posterior std: {result.posterior_std}")
|
|
193
|
+
print(f"Acceptance rate: {result.acceptance_rate:.2%}")
|
|
194
|
+
print(f"Samples shape: {result.samples.shape}") # (num_samples, 10)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Supported Public API
|
|
198
|
+
|
|
199
|
+
The library exposes three main entrypoints plus parallel tempering helpers:
|
|
200
|
+
|
|
201
|
+
1. **`estimate_with_optimizer`** — Complete pipeline (preprocessing + optimization)
|
|
202
|
+
2. **`run_multistart_minimization`** — Multistart L-BFGS-B optimization
|
|
203
|
+
3. **`run_mcmc_inference`** — Metropolis-Hastings MCMC sampling
|
|
204
|
+
4. **Parallel tempering** — `build_beta_ladder`, `sample_from_prior`, `run_parallel_tempering` for replica-exchange MCMC (see [API Reference](docs/API.md))
|
|
205
|
+
|
|
206
|
+
Each entrypoint has corresponding configuration and result dataclasses. See the [API Reference](docs/API.md) for complete documentation.
|
|
207
|
+
|
|
208
|
+
## Parameters
|
|
209
|
+
|
|
210
|
+
The beam model uses 10 parameters (in order):
|
|
211
|
+
|
|
212
|
+
| Index | Name | Description | Units |
|
|
213
|
+
|-------|------|-------------|-------|
|
|
214
|
+
| 0 | `Ax` | Horizontal raster amplitude | mm |
|
|
215
|
+
| 1 | `Ay` | Vertical raster amplitude | mm |
|
|
216
|
+
| 2 | `sigx` | Horizontal beam width (std dev) | mm |
|
|
217
|
+
| 3 | `sigy` | Vertical beam width (std dev) | mm |
|
|
218
|
+
| 4 | `cx` | Horizontal center offset | mm |
|
|
219
|
+
| 5 | `cy` | Vertical center offset | mm |
|
|
220
|
+
| 6 | `fx` | Horizontal scan frequency | kHz |
|
|
221
|
+
| 7 | `fy` | Vertical scan frequency | kHz |
|
|
222
|
+
| 8 | `phix` | Horizontal phase offset | radians |
|
|
223
|
+
| 9 | `phiy` | Vertical phase offset | radians |
|
|
224
|
+
|
|
225
|
+
## Configuration Guide
|
|
226
|
+
|
|
227
|
+
### OptimizerConfig
|
|
228
|
+
|
|
229
|
+
Controls the full pipeline (`estimate_with_optimizer`):
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
config = beam_infer.OptimizerConfig(
|
|
233
|
+
max_iterations=100, # Max L-BFGS-B iterations per run
|
|
234
|
+
multistart={"n_starts": 5, "type": "uniform"}, # Multistart config
|
|
235
|
+
regularization={"params": {"sigx": 0.1}}, # Regularization strengths
|
|
236
|
+
random_seed=42, # Optional: for reproducible multistart
|
|
237
|
+
verbose=False, # Print iteration details
|
|
238
|
+
debug=False, # Return intermediate results
|
|
239
|
+
)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Multistart options:**
|
|
243
|
+
- `"type": "uniform"` - Uniform random sampling within bounds
|
|
244
|
+
- `"type": "gaussian"` - Gaussian sampling around initial guess
|
|
245
|
+
|
|
246
|
+
**Regularization:**
|
|
247
|
+
- Dictionary mapping parameter names to penalty strengths
|
|
248
|
+
- Penalizes deviation from initial guess: `lambda * (param - param0)^2`
|
|
249
|
+
|
|
250
|
+
### MinimizationConfig
|
|
251
|
+
|
|
252
|
+
Controls single/multistart optimization:
|
|
253
|
+
|
|
254
|
+
```python
|
|
255
|
+
config = beam_infer.MinimizationConfig(
|
|
256
|
+
initial_guess=k0, # Initial parameter vector (10-D)
|
|
257
|
+
bounds=(lower, upper), # Optional: parameter bounds
|
|
258
|
+
max_iterations=100, # Max L-BFGS-B iterations
|
|
259
|
+
verbose=False, # Print iteration details
|
|
260
|
+
regularization={"sigx": 0.1}, # Optional: regularization strengths
|
|
261
|
+
)
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### MCMCConfig
|
|
265
|
+
|
|
266
|
+
Controls MCMC sampling:
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
config = beam_infer.MCMCConfig(
|
|
270
|
+
lower_bounds=lower, # Lower bounds (10-D array)
|
|
271
|
+
upper_bounds=upper, # Upper bounds (10-D array)
|
|
272
|
+
num_samples=4000, # Number of samples to collect
|
|
273
|
+
burn_in=1000, # Burn-in period
|
|
274
|
+
thin=2, # Thinning interval
|
|
275
|
+
prior_type="uniform", # "uniform" or "gaussian"
|
|
276
|
+
prior_mean=None, # Required for Gaussian prior
|
|
277
|
+
prior_std=None, # Required for Gaussian prior
|
|
278
|
+
proposal_std=None, # Optional: custom proposal std dev
|
|
279
|
+
seed=42, # Random seed
|
|
280
|
+
use_scan=True, # Use lax.scan (faster, default)
|
|
281
|
+
)
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## When to Use Which Method?
|
|
285
|
+
|
|
286
|
+
- **`estimate_with_optimizer`**: Use when you have a raw camera image and want a complete pipeline. Handles preprocessing, grid construction, and optimization automatically.
|
|
287
|
+
|
|
288
|
+
- **`run_multistart_minimization`**: Use when you need more control over preprocessing/grids, or want to run optimization from multiple starting points for robustness.
|
|
289
|
+
|
|
290
|
+
- **`run_mcmc_inference`**: Use when you need uncertainty quantification, want to explore the posterior distribution, or need Bayesian inference.
|
|
291
|
+
|
|
292
|
+
## Examples
|
|
293
|
+
|
|
294
|
+
See the `examples/` directory for complete examples:
|
|
295
|
+
|
|
296
|
+
- `simple_estimation.py` ⭐ - **Simplest example using only public API** (recommended for beginners)
|
|
297
|
+
- `basic_simulation.py` - Basic beam image generation
|
|
298
|
+
- `parameter_variations.py` - Effects of different parameters
|
|
299
|
+
- `raster_pattern.py` - Visualize raster scanning patterns
|
|
300
|
+
- `inference_example.py` - Parameter recovery from synthetic data
|
|
301
|
+
- `real_image_estimation.py` - **Real snapshot: optimizer + MCMC with comparison**
|
|
302
|
+
- `comprehensive_example.py` - Complete workflow demonstration
|
|
303
|
+
|
|
304
|
+
Run examples:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# Simplest example (public API only)
|
|
308
|
+
python -m examples.simple_estimation
|
|
309
|
+
|
|
310
|
+
# Real image: optimizer vs MCMC (requires beam snapshot NPZ in examples/)
|
|
311
|
+
python -m examples.real_image_estimation
|
|
312
|
+
|
|
313
|
+
# Comprehensive example (recommended)
|
|
314
|
+
python -m examples.comprehensive_example
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
See [examples/README.md](examples/README.md) for detailed documentation on all examples.
|
|
318
|
+
|
|
319
|
+
## Requirements
|
|
320
|
+
|
|
321
|
+
- Python >= 3.10
|
|
322
|
+
- numpy >= 1.20.0
|
|
323
|
+
- jax >= 0.4.0
|
|
324
|
+
- jaxlib >= 0.4.0
|
|
325
|
+
- scipy >= 1.7.0
|
|
326
|
+
|
|
327
|
+
### GPU Support (Optional)
|
|
328
|
+
|
|
329
|
+
For GPU acceleration, install JAX with CUDA support:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
# For CUDA 12.x
|
|
333
|
+
pip install --upgrade "jax[cuda12]" -f https://storage.googleapis.com/jax-releases/jax_cuda_release
|
|
334
|
+
|
|
335
|
+
# Verify GPU detection
|
|
336
|
+
python -c "import jax; print(jax.devices())"
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Development
|
|
340
|
+
|
|
341
|
+
### Running Tests
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
# After clone, fetch the reference implementation submodule (for equivalence tests)
|
|
345
|
+
git submodule update --init --recursive
|
|
346
|
+
|
|
347
|
+
pytest tests/
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Code Formatting
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
black beam_infer/ tests/ examples/
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Type Checking
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
mypy beam_infer/
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## License
|
|
363
|
+
|
|
364
|
+
MIT License - see LICENSE file for details.
|