goad-py 0.3.0__cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.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.
Potentially problematic release.
This version of goad-py might be problematic. Click here for more details.
- goad_py/__init__.py +5 -0
- goad_py/__init__.pyi +345 -0
- goad_py/goad_py.abi3.so +0 -0
- goad_py/py.typed +0 -0
- goad_py-0.3.0.dist-info/METADATA +71 -0
- goad_py-0.3.0.dist-info/RECORD +7 -0
- goad_py-0.3.0.dist-info/WHEEL +4 -0
goad_py/__init__.py
ADDED
goad_py/__init__.pyi
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
"""
|
|
2
|
+
GOAD Python API Type Definitions
|
|
3
|
+
|
|
4
|
+
This file provides comprehensive type hints for the GOAD (Geometric Optics
|
|
5
|
+
Approximation for Diffraction) Python bindings. GOAD simulates light scattering
|
|
6
|
+
by arbitrary 3D geometries using geometric optics with diffraction corrections.
|
|
7
|
+
|
|
8
|
+
The main workflow is:
|
|
9
|
+
1. Create Settings with geometry path (all other parameters have sensible defaults)
|
|
10
|
+
2. Use Problem for single-orientation or MultiProblem for multi-orientation simulations
|
|
11
|
+
3. Call py_solve() to run the computation
|
|
12
|
+
4. Access results through the .results property
|
|
13
|
+
|
|
14
|
+
Default behavior (minimal setup):
|
|
15
|
+
- Single random orientation (perfect for initial exploration)
|
|
16
|
+
- Interval angular binning with ~1000 bins (good coverage, reasonable performance)
|
|
17
|
+
- Wavelength: 532nm (green laser)
|
|
18
|
+
- Refractive index: 1.31 + 0.0i (typical glass particle in air)
|
|
19
|
+
|
|
20
|
+
Example (minimal setup):
|
|
21
|
+
import goad_py as goad
|
|
22
|
+
|
|
23
|
+
# Ultra-simple single orientation
|
|
24
|
+
settings = goad.Settings("particle.obj")
|
|
25
|
+
problem = goad.Problem(settings)
|
|
26
|
+
problem.py_solve()
|
|
27
|
+
print(f"Extinction: {problem.results.ext_cross}")
|
|
28
|
+
|
|
29
|
+
# Multi-orientation averaging (100 random orientations)
|
|
30
|
+
orientations = goad.create_uniform_orientation(100)
|
|
31
|
+
settings = goad.Settings("particle.obj", orientation=orientations)
|
|
32
|
+
mp = goad.MultiProblem(settings)
|
|
33
|
+
mp.py_solve()
|
|
34
|
+
print(f"Average extinction: {mp.results.ext_cross}")
|
|
35
|
+
|
|
36
|
+
# Truly minimal (just geometry path)
|
|
37
|
+
settings = goad.Settings("particle.obj") # Everything else uses defaults!
|
|
38
|
+
mp = goad.MultiProblem(settings)
|
|
39
|
+
mp.py_solve()
|
|
40
|
+
print(f"Results: {mp.results.scat_cross}")
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
from typing import Optional, List, Dict, Any, Union
|
|
44
|
+
|
|
45
|
+
class Euler:
|
|
46
|
+
"""Euler angles for rotations."""
|
|
47
|
+
alpha: float
|
|
48
|
+
beta: float
|
|
49
|
+
gamma: float
|
|
50
|
+
|
|
51
|
+
def __init__(self, alpha: float, beta: float, gamma: float) -> None: ...
|
|
52
|
+
def __repr__(self) -> str: ...
|
|
53
|
+
|
|
54
|
+
class EulerConvention:
|
|
55
|
+
"""Euler angle conventions."""
|
|
56
|
+
XZX: 'EulerConvention'
|
|
57
|
+
XYX: 'EulerConvention'
|
|
58
|
+
YXY: 'EulerConvention'
|
|
59
|
+
YZY: 'EulerConvention'
|
|
60
|
+
ZYZ: 'EulerConvention'
|
|
61
|
+
ZXZ: 'EulerConvention'
|
|
62
|
+
XZY: 'EulerConvention'
|
|
63
|
+
XYZ: 'EulerConvention'
|
|
64
|
+
YXZ: 'EulerConvention'
|
|
65
|
+
YZX: 'EulerConvention'
|
|
66
|
+
ZYX: 'EulerConvention'
|
|
67
|
+
ZXY: 'EulerConvention'
|
|
68
|
+
|
|
69
|
+
class Scheme:
|
|
70
|
+
"""Orientation scheme (uniform or discrete)."""
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
class Orientation:
|
|
74
|
+
"""Full orientation specification."""
|
|
75
|
+
scheme: Scheme
|
|
76
|
+
euler_convention: EulerConvention
|
|
77
|
+
|
|
78
|
+
def __init__(self, scheme: Scheme, euler_convention: Optional[EulerConvention] = None) -> None: ...
|
|
79
|
+
def __repr__(self) -> str: ...
|
|
80
|
+
|
|
81
|
+
class Geom:
|
|
82
|
+
"""Geometry representation."""
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
class Shape:
|
|
86
|
+
"""Shape within geometry."""
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
class Results:
|
|
90
|
+
"""Results from problem solving."""
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def bins(self) -> List[tuple[float, float]]: ...
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def bins_1d(self) -> Optional[List[float]]: ...
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def mueller(self) -> List[List[float]]: ...
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def mueller_beam(self) -> List[List[float]]: ...
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def mueller_ext(self) -> List[List[float]]: ...
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def mueller_1d(self) -> List[List[float]]: ...
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def mueller_1d_beam(self) -> List[List[float]]: ...
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def mueller_1d_ext(self) -> List[List[float]]: ...
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def asymmetry(self) -> Optional[float]: ...
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def scat_cross(self) -> Optional[float]: ...
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def ext_cross(self) -> Optional[float]: ...
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def albedo(self) -> Optional[float]: ...
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def params(self) -> Dict[str, Optional[float]]: ...
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def powers(self) -> Dict[str, float]: ...
|
|
133
|
+
|
|
134
|
+
class BinningScheme:
|
|
135
|
+
"""Angular binning scheme for scattering calculations.
|
|
136
|
+
|
|
137
|
+
Defines how to discretize the scattering sphere into angular bins
|
|
138
|
+
for Mueller matrix and amplitude computations. Supports simple
|
|
139
|
+
regular grids, custom intervals, and arbitrary bin arrangements.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
def __init__(self, bins: List[tuple[float, float]]) -> None: ...
|
|
143
|
+
|
|
144
|
+
@staticmethod
|
|
145
|
+
def simple(num_theta: int, num_phi: int) -> 'BinningScheme':
|
|
146
|
+
"""Create a simple regular grid binning scheme.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
num_theta: Number of bins in theta direction (0 to 180 degrees)
|
|
150
|
+
num_phi: Number of bins in phi direction (0 to 360 degrees)
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
BinningScheme with regular angular grid
|
|
154
|
+
|
|
155
|
+
Raises:
|
|
156
|
+
ValueError: If num_theta or num_phi is zero or negative
|
|
157
|
+
"""
|
|
158
|
+
...
|
|
159
|
+
|
|
160
|
+
@staticmethod
|
|
161
|
+
def interval(
|
|
162
|
+
thetas: List[float],
|
|
163
|
+
theta_spacings: List[float],
|
|
164
|
+
phis: List[float],
|
|
165
|
+
phi_spacings: List[float]
|
|
166
|
+
) -> 'BinningScheme':
|
|
167
|
+
"""Create binning scheme with custom intervals.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
thetas: Key theta angles in degrees
|
|
171
|
+
theta_spacings: Spacing around each theta value
|
|
172
|
+
phis: Key phi angles in degrees
|
|
173
|
+
phi_spacings: Spacing around each phi value
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
BinningScheme with custom intervals
|
|
177
|
+
"""
|
|
178
|
+
...
|
|
179
|
+
|
|
180
|
+
@staticmethod
|
|
181
|
+
def custom(bins: List[tuple[float, float]]) -> 'BinningScheme':
|
|
182
|
+
"""Create binning scheme from explicit (theta, phi) pairs.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
bins: List of (theta, phi) angle pairs in degrees
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
BinningScheme with custom bin locations
|
|
189
|
+
"""
|
|
190
|
+
...
|
|
191
|
+
|
|
192
|
+
class Settings:
|
|
193
|
+
"""Simulation parameters and physical properties.
|
|
194
|
+
|
|
195
|
+
Contains all parameters needed for a GOAD simulation including
|
|
196
|
+
geometry path, optical properties, orientation scheme, and
|
|
197
|
+
numerical settings. Most parameters have sensible defaults.
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
def __init__(
|
|
201
|
+
self,
|
|
202
|
+
geom_path: str,
|
|
203
|
+
wavelength: float = 0.532,
|
|
204
|
+
particle_refr_index_re: float = 1.31,
|
|
205
|
+
particle_refr_index_im: float = 0.0,
|
|
206
|
+
medium_refr_index_re: float = 1.0,
|
|
207
|
+
medium_refr_index_im: float = 0.0,
|
|
208
|
+
orientation: Optional[Orientation] = None,
|
|
209
|
+
binning: Optional[BinningScheme] = None,
|
|
210
|
+
beam_power_threshold: float = 0.005,
|
|
211
|
+
beam_area_threshold_fac: float = 0.1,
|
|
212
|
+
cutoff: float = 0.99,
|
|
213
|
+
max_rec: int = 10,
|
|
214
|
+
max_tir: int = 10,
|
|
215
|
+
scale: float = 1.0,
|
|
216
|
+
directory: str = "goad_run"
|
|
217
|
+
) -> None:
|
|
218
|
+
"""Initialize simulation settings.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
geom_path: Path to geometry file (.obj format)
|
|
222
|
+
wavelength: Incident wavelength in geometry units (default: 0.532)
|
|
223
|
+
particle_refr_index_re: Real part of particle refractive index (default: 1.31)
|
|
224
|
+
particle_refr_index_im: Imaginary part of particle refractive index (default: 0.0)
|
|
225
|
+
medium_refr_index_re: Real part of medium refractive index (default: 1.0)
|
|
226
|
+
medium_refr_index_im: Imaginary part of medium refractive index (default: 0.0)
|
|
227
|
+
orientation: Orientation scheme (default: None → 1 random uniform orientation)
|
|
228
|
+
binning: Angular binning scheme (default: None → interval binning: theta=[0°,30°,60°,120°,180°] with spacings [2°,5°,10°,5°], phi=[0°,90°,180°,270°,360°] with 15° spacings, creating ~1000 bins)
|
|
229
|
+
beam_power_threshold: Ray termination threshold (default: 0.005)
|
|
230
|
+
beam_area_threshold_fac: Area threshold factor (default: 0.1)
|
|
231
|
+
cutoff: Power cutoff fraction 0-1 (default: 0.99)
|
|
232
|
+
max_rec: Maximum recursion depth (default: 10)
|
|
233
|
+
max_tir: Maximum total internal reflections (default: 10)
|
|
234
|
+
scale: Geometry scaling factor (default: 1.0)
|
|
235
|
+
directory: Output directory for results (default: "goad_run")
|
|
236
|
+
|
|
237
|
+
Raises:
|
|
238
|
+
ValueError: If wavelength <= 0 or cutoff not in [0,1]
|
|
239
|
+
FileNotFoundError: If geometry file doesn't exist
|
|
240
|
+
"""
|
|
241
|
+
...
|
|
242
|
+
|
|
243
|
+
@property
|
|
244
|
+
def euler(self) -> List[float]: ...
|
|
245
|
+
|
|
246
|
+
@euler.setter
|
|
247
|
+
def euler(self, value: List[float]) -> None: ...
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def orientation(self) -> Orientation: ...
|
|
251
|
+
|
|
252
|
+
@orientation.setter
|
|
253
|
+
def orientation(self, value: Orientation) -> None: ...
|
|
254
|
+
|
|
255
|
+
class Problem:
|
|
256
|
+
"""Single orientation problem."""
|
|
257
|
+
|
|
258
|
+
def __init__(self, settings: Optional[Settings] = None, geom: Optional[Geom] = None) -> None: ...
|
|
259
|
+
|
|
260
|
+
def py_solve(self) -> None: ...
|
|
261
|
+
|
|
262
|
+
def py_print_stats(self) -> None: ...
|
|
263
|
+
|
|
264
|
+
@property
|
|
265
|
+
def results(self) -> Results: ...
|
|
266
|
+
|
|
267
|
+
class MultiProblem:
|
|
268
|
+
"""Multi-orientation light scattering simulation for a single geometry.
|
|
269
|
+
|
|
270
|
+
Computes orientation-averaged scattering properties by running multiple
|
|
271
|
+
single-orientation simulations and averaging the results. Supports both
|
|
272
|
+
random and systematic orientation sampling schemes. Results include
|
|
273
|
+
Mueller matrices, cross-sections, and derived optical parameters.
|
|
274
|
+
|
|
275
|
+
Example:
|
|
276
|
+
orientations = goad.create_uniform_orientation(100)
|
|
277
|
+
settings = goad.Settings("particle.obj", orientation=orientations)
|
|
278
|
+
mp = goad.MultiProblem(settings)
|
|
279
|
+
mp.py_solve()
|
|
280
|
+
print(f"Scattering cross-section: {mp.results.scat_cross}")
|
|
281
|
+
"""
|
|
282
|
+
|
|
283
|
+
def __init__(self, settings: Settings, geom: Optional[Geom] = None) -> None:
|
|
284
|
+
"""Initialize multi-orientation problem.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
settings: Simulation parameters including orientation scheme
|
|
288
|
+
geom: Geometry object (loaded from settings.geom_path if None)
|
|
289
|
+
|
|
290
|
+
Raises:
|
|
291
|
+
FileNotFoundError: If geometry file cannot be loaded
|
|
292
|
+
"""
|
|
293
|
+
...
|
|
294
|
+
|
|
295
|
+
def py_solve(self) -> None:
|
|
296
|
+
"""Solve the multi-orientation scattering problem.
|
|
297
|
+
|
|
298
|
+
Computes scattering properties averaged over all orientations using
|
|
299
|
+
parallel processing. The Global Interpreter Lock (GIL) is released
|
|
300
|
+
during computation to allow concurrent Python operations.
|
|
301
|
+
|
|
302
|
+
Raises:
|
|
303
|
+
RuntimeError: If computation fails
|
|
304
|
+
"""
|
|
305
|
+
...
|
|
306
|
+
|
|
307
|
+
def py_writeup(self) -> None:
|
|
308
|
+
"""Write results to output files in the specified directory."""
|
|
309
|
+
...
|
|
310
|
+
|
|
311
|
+
def py_reset(self) -> None:
|
|
312
|
+
"""Reset problem to initial state and regenerate orientations."""
|
|
313
|
+
...
|
|
314
|
+
|
|
315
|
+
def py_regenerate_orientations(self) -> None:
|
|
316
|
+
"""Regenerate random orientations (useful for statistical sampling)."""
|
|
317
|
+
...
|
|
318
|
+
|
|
319
|
+
@property
|
|
320
|
+
def results(self) -> Results:
|
|
321
|
+
"""Access orientation-averaged simulation results.
|
|
322
|
+
|
|
323
|
+
Returns the complete Results object containing Mueller matrices,
|
|
324
|
+
amplitude matrices, power distributions, and derived parameters
|
|
325
|
+
averaged over all orientations.
|
|
326
|
+
"""
|
|
327
|
+
...
|
|
328
|
+
|
|
329
|
+
@property
|
|
330
|
+
def num_orientations(self) -> int:
|
|
331
|
+
"""Number of orientations in the current simulation."""
|
|
332
|
+
...
|
|
333
|
+
|
|
334
|
+
# Helper functions
|
|
335
|
+
def uniform_orientation(num_orients: int) -> Scheme: ...
|
|
336
|
+
|
|
337
|
+
def discrete_orientation(eulers: List[Euler]) -> Scheme: ...
|
|
338
|
+
|
|
339
|
+
def create_uniform_orientation(num_orients: int, euler_convention: Optional[EulerConvention] = None) -> Orientation: ...
|
|
340
|
+
|
|
341
|
+
def create_discrete_orientation(eulers: List[Euler], euler_convention: Optional[EulerConvention] = None) -> Orientation: ...
|
|
342
|
+
|
|
343
|
+
def sum_as_string(a: int, b: int) -> str: ...
|
|
344
|
+
|
|
345
|
+
def goad_py_add() -> None: ...
|
goad_py/goad_py.abi3.so
ADDED
|
Binary file
|
goad_py/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: goad-py
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Science/Research
|
|
6
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
7
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
8
|
+
Classifier: Programming Language :: Rust
|
|
9
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
10
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Summary: Physical optics light scattering computation
|
|
19
|
+
Keywords: light-scattering,optics,simulation,scientific-computing,physics
|
|
20
|
+
Home-Page: https://github.com/hballington12/goad
|
|
21
|
+
Author-email: Harry Ballington <ballington@uni-wuppertal.de>
|
|
22
|
+
License: GPL-3.0
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
25
|
+
Project-URL: Homepage, https://github.com/hballington12/goad
|
|
26
|
+
Project-URL: Documentation, https://docs.rs/goad/0.1.0/goad/index.html
|
|
27
|
+
Project-URL: Repository, https://github.com/hballington12/goad
|
|
28
|
+
Project-URL: Rust Crate, https://crates.io/crates/goad
|
|
29
|
+
|
|
30
|
+
# GOAD-PY
|
|
31
|
+
|
|
32
|
+
Python bindings for GOAD (Geometric Optics Approximation with Diffraction) - a physical optics light scattering computation library.
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install goad-py
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
import goad_py
|
|
44
|
+
|
|
45
|
+
# Create a problem with minimal setup
|
|
46
|
+
problem = goad_py.Problem("path/to/geometry.obj")
|
|
47
|
+
|
|
48
|
+
# Solve and get results
|
|
49
|
+
results = problem.py_solve()
|
|
50
|
+
|
|
51
|
+
# Access scattering data
|
|
52
|
+
print(f"Number of angles: {results.num_angles}")
|
|
53
|
+
print(f"Scattering cross section: {results.sca_cross_section}")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Features
|
|
57
|
+
|
|
58
|
+
- Fast light scattering computations using physical optics
|
|
59
|
+
- Support for various 3D geometry formats
|
|
60
|
+
- Configurable wavelength, refractive index, and orientations
|
|
61
|
+
- Multi-orientation averaging capabilities
|
|
62
|
+
- Efficient parallel computation with GIL release
|
|
63
|
+
|
|
64
|
+
## Documentation
|
|
65
|
+
|
|
66
|
+
- [Rust API Documentation](https://docs.rs/goad/0.1.0/goad/index.html)
|
|
67
|
+
- [GitHub Repository](https://github.com/hballington12/goad)
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
GPL-3.0 License - see the LICENSE file in the main repository for details.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
goad_py-0.3.0.dist-info/METADATA,sha256=_QAoI_pML6HmYtVhYwEzjAjrZ1ieYWmib0Hk0QRvDGI,2434
|
|
2
|
+
goad_py-0.3.0.dist-info/WHEEL,sha256=GI7AtqFZ5ODwygoOptTlPSGOTs6AS7-pDnbqjA70obA,129
|
|
3
|
+
goad_py/__init__.py,sha256=YW_7ejLyMUb8grQQmBo-vpbgTYF2xRruw6x7UxAerIg,111
|
|
4
|
+
goad_py/__init__.pyi,sha256=Fc4JBBbKMYZ0MA_DzycbC2v19YARzGKNg0bfmTkNhPQ,11489
|
|
5
|
+
goad_py/goad_py.abi3.so,sha256=aUeENrGWRE50D-Veekb0i7MfHHN1IUAYL1-XXxMoZp8,2431032
|
|
6
|
+
goad_py/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
goad_py-0.3.0.dist-info/RECORD,,
|