goad-py 0.7.0__cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.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/goad_py.pyi ADDED
@@ -0,0 +1,453 @@
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
+ settings = goad.Settings("particle.obj")
24
+ mp = goad.MultiProblem(settings)
25
+ mp.py_solve()
26
+
27
+ results = mp.results
28
+ print(f"Scattering cross-section: {results.scat_cross}")
29
+ print(f"Extinction cross-section: {results.ext_cross}")
30
+ print(f"Asymmetry parameter: {results.asymmetry}")
31
+ """
32
+
33
+ from typing import Optional, List, Dict, Tuple
34
+ import numpy as np
35
+
36
+ class Euler:
37
+ """Euler angles for rotations."""
38
+ alpha: float
39
+ beta: float
40
+ gamma: float
41
+
42
+ def __init__(self, alpha: float, beta: float, gamma: float) -> None: ...
43
+ def __repr__(self) -> str: ...
44
+
45
+ class EulerConvention:
46
+ """Euler angle conventions."""
47
+ XZX: 'EulerConvention'
48
+ XYX: 'EulerConvention'
49
+ YXY: 'EulerConvention'
50
+ YZY: 'EulerConvention'
51
+ ZYZ: 'EulerConvention'
52
+ ZXZ: 'EulerConvention'
53
+ XZY: 'EulerConvention'
54
+ XYZ: 'EulerConvention'
55
+ YXZ: 'EulerConvention'
56
+ YZX: 'EulerConvention'
57
+ ZYX: 'EulerConvention'
58
+ ZXY: 'EulerConvention'
59
+
60
+ class Scheme:
61
+ """Orientation scheme (uniform or discrete)."""
62
+ pass
63
+
64
+ class Orientation:
65
+ """Full orientation specification."""
66
+ scheme: Scheme
67
+ euler_convention: EulerConvention
68
+
69
+ def __init__(self, scheme: Scheme, euler_convention: Optional[EulerConvention] = None) -> None: ...
70
+ def __repr__(self) -> str: ...
71
+
72
+ class Geom:
73
+ """Geometry representation."""
74
+ pass
75
+
76
+ class Shape:
77
+ """Shape within geometry."""
78
+ pass
79
+
80
+ class Results:
81
+ """Results from problem solving."""
82
+
83
+ @property
84
+ def bins(self) -> List[tuple[float, float]]: ...
85
+
86
+ @property
87
+ def bins_1d(self) -> Optional[List[float]]: ...
88
+
89
+ @property
90
+ def mueller(self) -> List[List[float]]: ...
91
+
92
+ @property
93
+ def mueller_beam(self) -> List[List[float]]: ...
94
+
95
+ @property
96
+ def mueller_ext(self) -> List[List[float]]: ...
97
+
98
+ @property
99
+ def mueller_1d(self) -> List[List[float]]: ...
100
+
101
+ @property
102
+ def mueller_1d_beam(self) -> List[List[float]]: ...
103
+
104
+ @property
105
+ def mueller_1d_ext(self) -> List[List[float]]: ...
106
+
107
+ @property
108
+ def asymmetry(self) -> Optional[float]: ...
109
+
110
+ @property
111
+ def scat_cross(self) -> Optional[float]: ...
112
+
113
+ @property
114
+ def ext_cross(self) -> Optional[float]: ...
115
+
116
+ @property
117
+ def albedo(self) -> Optional[float]: ...
118
+
119
+ @property
120
+ def params(self) -> Dict[str, Optional[float]]: ...
121
+
122
+ @property
123
+ def powers(self) -> Dict[str, float]: ...
124
+
125
+ class BinningScheme:
126
+ """Angular binning scheme for scattering calculations.
127
+
128
+ Defines how to discretize the scattering sphere into angular bins
129
+ for Mueller matrix and amplitude computations. Supports simple
130
+ regular grids, custom intervals, and arbitrary bin arrangements.
131
+ """
132
+
133
+ def __init__(self, bins: List[tuple[float, float]]) -> None: ...
134
+
135
+ @staticmethod
136
+ def simple(num_theta: int, num_phi: int) -> 'BinningScheme':
137
+ """Create a simple regular grid binning scheme.
138
+
139
+ Args:
140
+ num_theta: Number of bins in theta direction (0 to 180 degrees)
141
+ num_phi: Number of bins in phi direction (0 to 360 degrees)
142
+
143
+ Returns:
144
+ BinningScheme with regular angular grid
145
+
146
+ Raises:
147
+ ValueError: If num_theta or num_phi is zero or negative
148
+ """
149
+ ...
150
+
151
+ @staticmethod
152
+ def interval(
153
+ thetas: List[float],
154
+ theta_spacings: List[float],
155
+ phis: List[float],
156
+ phi_spacings: List[float]
157
+ ) -> 'BinningScheme':
158
+ """Create binning scheme with custom intervals.
159
+
160
+ Args:
161
+ thetas: Key theta angles in degrees
162
+ theta_spacings: Spacing around each theta value
163
+ phis: Key phi angles in degrees
164
+ phi_spacings: Spacing around each phi value
165
+
166
+ Returns:
167
+ BinningScheme with custom intervals
168
+ """
169
+ ...
170
+
171
+ @staticmethod
172
+ def custom(bins: List[tuple[float, float]]) -> 'BinningScheme':
173
+ """Create binning scheme from explicit (theta, phi) pairs.
174
+
175
+ Args:
176
+ bins: List of (theta, phi) angle pairs in degrees
177
+
178
+ Returns:
179
+ BinningScheme with custom bin locations
180
+ """
181
+ ...
182
+
183
+ class Settings:
184
+ """Simulation parameters and physical properties.
185
+
186
+ Contains all parameters needed for a GOAD simulation including
187
+ geometry path, optical properties, orientation scheme, and
188
+ numerical settings. Most parameters have sensible defaults.
189
+ """
190
+
191
+ def __init__(
192
+ self,
193
+ geom_path: str,
194
+ wavelength: float = 0.532,
195
+ particle_refr_index_re: float = 1.31,
196
+ particle_refr_index_im: float = 0.0,
197
+ medium_refr_index_re: float = 1.0,
198
+ medium_refr_index_im: float = 0.0,
199
+ orientation: Optional[Orientation] = None,
200
+ binning: Optional[BinningScheme] = None,
201
+ beam_power_threshold: float = 0.005,
202
+ beam_area_threshold_fac: float = 0.1,
203
+ cutoff: float = 0.99,
204
+ max_rec: int = 10,
205
+ max_tir: int = 10,
206
+ scale: float = 1.0,
207
+ directory: str = "goad_run"
208
+ ) -> None:
209
+ """Initialize simulation settings.
210
+
211
+ Args:
212
+ geom_path: Path to geometry file (.obj format)
213
+ wavelength: Incident wavelength in geometry units (default: 0.532)
214
+ particle_refr_index_re: Real part of particle refractive index (default: 1.31)
215
+ particle_refr_index_im: Imaginary part of particle refractive index (default: 0.0)
216
+ medium_refr_index_re: Real part of medium refractive index (default: 1.0)
217
+ medium_refr_index_im: Imaginary part of medium refractive index (default: 0.0)
218
+ orientation: Orientation scheme (default: None → 1 random uniform orientation)
219
+ 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)
220
+ beam_power_threshold: Ray termination threshold (default: 0.005)
221
+ beam_area_threshold_fac: Area threshold factor (default: 0.1)
222
+ cutoff: Power cutoff fraction 0-1 (default: 0.99)
223
+ max_rec: Maximum recursion depth (default: 10)
224
+ max_tir: Maximum total internal reflections (default: 10)
225
+ scale: Geometry scaling factor (default: 1.0)
226
+ directory: Output directory for results (default: "goad_run")
227
+
228
+ Raises:
229
+ ValueError: If wavelength <= 0 or cutoff not in [0,1]
230
+ FileNotFoundError: If geometry file doesn't exist
231
+ """
232
+ ...
233
+
234
+ @property
235
+ def euler(self) -> List[float]: ...
236
+
237
+ @euler.setter
238
+ def euler(self, value: List[float]) -> None: ...
239
+
240
+ @property
241
+ def orientation(self) -> Orientation: ...
242
+
243
+ @orientation.setter
244
+ def orientation(self, value: Orientation) -> None: ...
245
+
246
+ class Problem:
247
+ """Single orientation problem."""
248
+
249
+ def __init__(self, settings: Optional[Settings] = None, geom: Optional[Geom] = None) -> None: ...
250
+
251
+ def py_solve(self) -> None: ...
252
+
253
+ def py_print_stats(self) -> None: ...
254
+
255
+ @property
256
+ def results(self) -> Results: ...
257
+
258
+ class MultiProblem:
259
+ """Multi-orientation light scattering simulation for a single geometry.
260
+
261
+ Computes orientation-averaged scattering properties by running multiple
262
+ single-orientation simulations and averaging the results. Supports both
263
+ random and systematic orientation sampling schemes. Results include
264
+ Mueller matrices, cross-sections, and derived optical parameters.
265
+
266
+ Example:
267
+ orientations = goad.create_uniform_orientation(100)
268
+ settings = goad.Settings("particle.obj", orientation=orientations)
269
+ mp = goad.MultiProblem(settings)
270
+ mp.py_solve()
271
+ print(f"Scattering cross-section: {mp.results.scat_cross}")
272
+ """
273
+
274
+ def __init__(self, settings: Settings, geom: Optional[Geom] = None) -> None:
275
+ """Initialize multi-orientation problem.
276
+
277
+ Args:
278
+ settings: Simulation parameters including orientation scheme
279
+ geom: Geometry object (loaded from settings.geom_path if None)
280
+
281
+ Raises:
282
+ FileNotFoundError: If geometry file cannot be loaded
283
+ """
284
+ ...
285
+
286
+ def py_solve(self) -> None:
287
+ """Solve the multi-orientation scattering problem.
288
+
289
+ Computes scattering properties averaged over all orientations using
290
+ parallel processing. The Global Interpreter Lock (GIL) is released
291
+ during computation to allow concurrent Python operations.
292
+
293
+ Raises:
294
+ RuntimeError: If computation fails
295
+ """
296
+ ...
297
+
298
+ def py_writeup(self) -> None:
299
+ """Write results to output files in the specified directory."""
300
+ ...
301
+
302
+ def py_reset(self) -> None:
303
+ """Reset problem to initial state and regenerate orientations."""
304
+ ...
305
+
306
+ def py_regenerate_orientations(self) -> None:
307
+ """Regenerate random orientations (useful for statistical sampling)."""
308
+ ...
309
+
310
+ @property
311
+ def results(self) -> Results:
312
+ """Access orientation-averaged simulation results.
313
+
314
+ Returns the complete Results object containing Mueller matrices,
315
+ amplitude matrices, power distributions, and derived parameters
316
+ averaged over all orientations.
317
+ """
318
+ ...
319
+
320
+ @property
321
+ def num_orientations(self) -> int:
322
+ """Number of orientations in the current simulation."""
323
+ ...
324
+
325
+ # Helper functions
326
+ def uniform_orientation(num_orients: int) -> Scheme: ...
327
+
328
+ def discrete_orientation(eulers: List[Euler]) -> Scheme: ...
329
+
330
+ def create_uniform_orientation(num_orients: int, euler_convention: Optional[EulerConvention] = None) -> Orientation: ...
331
+
332
+ def create_discrete_orientation(eulers: List[Euler], euler_convention: Optional[EulerConvention] = None) -> Orientation: ...
333
+
334
+ def sum_as_string(a: int, b: int) -> str: ...
335
+
336
+ def goad_py_add() -> None: ...
337
+
338
+ # Convergence Analysis Classes
339
+
340
+ class Convergable:
341
+ """Represents a variable to monitor for convergence.
342
+
343
+ Defines convergence criteria for integrated scattering parameters
344
+ including asymmetry parameter, scattering cross-section, extinction
345
+ cross-section, and single-scattering albedo.
346
+ """
347
+
348
+ variable: str
349
+ tolerance_type: str
350
+ tolerance: float
351
+
352
+ def __init__(
353
+ self,
354
+ variable: str,
355
+ tolerance_type: str = 'relative',
356
+ tolerance: float = 0.01
357
+ ) -> None:
358
+ """Initialize convergence criterion.
359
+
360
+ Args:
361
+ variable: Variable to monitor ('asymmetry', 'scatt', 'ext', 'albedo')
362
+ tolerance_type: 'relative' or 'absolute' tolerance
363
+ tolerance: Tolerance value (relative as fraction, absolute as value)
364
+
365
+ Raises:
366
+ ValueError: If variable name or tolerance_type is invalid
367
+ """
368
+ ...
369
+
370
+ class ConvergenceResults:
371
+ """Results from a convergence study.
372
+
373
+ Contains final convergence status, parameter values with uncertainties,
374
+ and complete convergence history for analysis.
375
+ """
376
+
377
+ converged: bool
378
+ n_orientations: int
379
+ values: Dict[str, float]
380
+ sem_values: Dict[str, float]
381
+ mueller_1d: Optional[np.ndarray]
382
+ mueller_2d: Optional[np.ndarray]
383
+ convergence_history: List[Tuple[int, str, float]]
384
+ warning: Optional[str]
385
+
386
+ def __init__(
387
+ self,
388
+ converged: bool,
389
+ n_orientations: int,
390
+ values: Dict[str, float],
391
+ sem_values: Dict[str, float],
392
+ mueller_1d: Optional[np.ndarray] = None,
393
+ mueller_2d: Optional[np.ndarray] = None,
394
+ convergence_history: List[Tuple[int, str, float]] = None,
395
+ warning: Optional[str] = None
396
+ ) -> None: ...
397
+
398
+ class Convergence:
399
+ """Runs multiple MultiProblems until convergence criteria are met.
400
+
401
+ Implements statistical convergence analysis for scattering parameters
402
+ using batch-based standard error estimation. Monitors multiple variables
403
+ simultaneously and stops when all meet their convergence criteria.
404
+
405
+ Example:
406
+ convergence = Convergence(
407
+ settings=goad.Settings("particle.obj"),
408
+ convergables=[
409
+ Convergable('asymmetry', 'absolute', 0.005),
410
+ Convergable('scatt', 'relative', 0.01),
411
+ ],
412
+ batch_size=100
413
+ )
414
+ results = convergence.run()
415
+ """
416
+
417
+ def __init__(
418
+ self,
419
+ settings: Settings,
420
+ convergables: List[Convergable],
421
+ batch_size: int = 24,
422
+ max_orientations: int = 100_000,
423
+ min_batches: int = 10,
424
+ mueller_1d: bool = True,
425
+ mueller_2d: bool = False
426
+ ) -> None:
427
+ """Initialize convergence study.
428
+
429
+ Args:
430
+ settings: GOAD settings for the simulation
431
+ convergables: List of variables to monitor for convergence
432
+ batch_size: Number of orientations per iteration
433
+ max_orientations: Maximum total orientations before stopping
434
+ min_batches: Minimum number of batches before allowing convergence
435
+ mueller_1d: Whether to collect 1D Mueller matrices
436
+ mueller_2d: Whether to collect 2D Mueller matrices
437
+
438
+ Raises:
439
+ ValueError: If parameters are invalid or no convergables specified
440
+ """
441
+ ...
442
+
443
+ def run(self) -> ConvergenceResults:
444
+ """Run the convergence study.
445
+
446
+ Executes batches of orientations until all convergence criteria
447
+ are met or maximum orientations reached. Provides progress updates
448
+ and rigorous statistical analysis.
449
+
450
+ Returns:
451
+ ConvergenceResults containing final values and convergence status
452
+ """
453
+ ...