lsurf 1.0.0__py3-none-any.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.
- lsurf/__init__.py +471 -0
- lsurf/analysis/__init__.py +107 -0
- lsurf/analysis/healpix_utils.py +418 -0
- lsurf/analysis/sphere_viz.py +1280 -0
- lsurf/cli/__init__.py +48 -0
- lsurf/cli/build.py +398 -0
- lsurf/cli/config_schema.py +318 -0
- lsurf/cli/gui_cmd.py +76 -0
- lsurf/cli/interactive.py +850 -0
- lsurf/cli/main.py +81 -0
- lsurf/cli/run.py +806 -0
- lsurf/detectors/__init__.py +266 -0
- lsurf/detectors/analysis.py +289 -0
- lsurf/detectors/base.py +284 -0
- lsurf/detectors/constant_size_rings.py +485 -0
- lsurf/detectors/directional.py +45 -0
- lsurf/detectors/extended/__init__.py +73 -0
- lsurf/detectors/extended/local_sphere.py +353 -0
- lsurf/detectors/extended/recording_sphere.py +368 -0
- lsurf/detectors/planar.py +45 -0
- lsurf/detectors/protocol.py +187 -0
- lsurf/detectors/recording_spheres.py +63 -0
- lsurf/detectors/results.py +1140 -0
- lsurf/detectors/small/__init__.py +79 -0
- lsurf/detectors/small/directional.py +330 -0
- lsurf/detectors/small/planar.py +401 -0
- lsurf/detectors/small/spherical.py +450 -0
- lsurf/detectors/spherical.py +45 -0
- lsurf/geometry/__init__.py +199 -0
- lsurf/geometry/builder.py +478 -0
- lsurf/geometry/cell.py +228 -0
- lsurf/geometry/cell_geometry.py +247 -0
- lsurf/geometry/detector_arrays.py +1785 -0
- lsurf/geometry/geometry.py +222 -0
- lsurf/geometry/surface_analysis.py +375 -0
- lsurf/geometry/validation.py +91 -0
- lsurf/gui/__init__.py +51 -0
- lsurf/gui/app.py +903 -0
- lsurf/gui/core/__init__.py +39 -0
- lsurf/gui/core/scene.py +343 -0
- lsurf/gui/core/simulation.py +264 -0
- lsurf/gui/renderers/__init__.py +40 -0
- lsurf/gui/renderers/ray_renderer.py +353 -0
- lsurf/gui/renderers/source_renderer.py +505 -0
- lsurf/gui/renderers/surface_renderer.py +477 -0
- lsurf/gui/views/__init__.py +48 -0
- lsurf/gui/views/config_editor.py +3199 -0
- lsurf/gui/views/properties.py +257 -0
- lsurf/gui/views/results.py +291 -0
- lsurf/gui/views/scene_tree.py +180 -0
- lsurf/gui/views/viewport_3d.py +555 -0
- lsurf/gui/views/visualizations.py +712 -0
- lsurf/materials/__init__.py +169 -0
- lsurf/materials/base/__init__.py +64 -0
- lsurf/materials/base/full_inhomogeneous.py +208 -0
- lsurf/materials/base/grid_inhomogeneous.py +319 -0
- lsurf/materials/base/homogeneous.py +342 -0
- lsurf/materials/base/material_field.py +527 -0
- lsurf/materials/base/simple_inhomogeneous.py +418 -0
- lsurf/materials/base/spectral_inhomogeneous.py +497 -0
- lsurf/materials/implementations/__init__.py +120 -0
- lsurf/materials/implementations/data/alpha_values_typical_atmosphere_updated.txt +24 -0
- lsurf/materials/implementations/duct_atmosphere.py +390 -0
- lsurf/materials/implementations/exponential_atmosphere.py +435 -0
- lsurf/materials/implementations/gaussian_lens.py +120 -0
- lsurf/materials/implementations/interpolated_data.py +123 -0
- lsurf/materials/implementations/layered_atmosphere.py +134 -0
- lsurf/materials/implementations/linear_gradient.py +109 -0
- lsurf/materials/implementations/linsley_atmosphere.py +764 -0
- lsurf/materials/implementations/standard_materials.py +126 -0
- lsurf/materials/implementations/turbulent_atmosphere.py +135 -0
- lsurf/materials/implementations/us_standard_atmosphere.py +149 -0
- lsurf/materials/utils/__init__.py +77 -0
- lsurf/materials/utils/constants.py +45 -0
- lsurf/materials/utils/device_functions.py +117 -0
- lsurf/materials/utils/dispersion.py +160 -0
- lsurf/materials/utils/factories.py +142 -0
- lsurf/propagation/__init__.py +91 -0
- lsurf/propagation/detector_gpu.py +67 -0
- lsurf/propagation/gpu_device_rays.py +294 -0
- lsurf/propagation/kernels/__init__.py +175 -0
- lsurf/propagation/kernels/absorption/__init__.py +61 -0
- lsurf/propagation/kernels/absorption/grid.py +240 -0
- lsurf/propagation/kernels/absorption/simple.py +232 -0
- lsurf/propagation/kernels/absorption/spectral.py +410 -0
- lsurf/propagation/kernels/detection/__init__.py +64 -0
- lsurf/propagation/kernels/detection/protocol.py +102 -0
- lsurf/propagation/kernels/detection/spherical.py +255 -0
- lsurf/propagation/kernels/device_functions.py +790 -0
- lsurf/propagation/kernels/fresnel/__init__.py +64 -0
- lsurf/propagation/kernels/fresnel/protocol.py +97 -0
- lsurf/propagation/kernels/fresnel/standard.py +258 -0
- lsurf/propagation/kernels/intersection/__init__.py +79 -0
- lsurf/propagation/kernels/intersection/annular_plane.py +207 -0
- lsurf/propagation/kernels/intersection/bounded_plane.py +205 -0
- lsurf/propagation/kernels/intersection/plane.py +166 -0
- lsurf/propagation/kernels/intersection/protocol.py +95 -0
- lsurf/propagation/kernels/intersection/signed_distance.py +742 -0
- lsurf/propagation/kernels/intersection/sphere.py +190 -0
- lsurf/propagation/kernels/propagation/__init__.py +85 -0
- lsurf/propagation/kernels/propagation/grid.py +527 -0
- lsurf/propagation/kernels/propagation/protocol.py +105 -0
- lsurf/propagation/kernels/propagation/simple.py +460 -0
- lsurf/propagation/kernels/propagation/spectral.py +875 -0
- lsurf/propagation/kernels/registry.py +331 -0
- lsurf/propagation/kernels/surface/__init__.py +72 -0
- lsurf/propagation/kernels/surface/bisection.py +232 -0
- lsurf/propagation/kernels/surface/detection.py +402 -0
- lsurf/propagation/kernels/surface/reduction.py +166 -0
- lsurf/propagation/propagator_protocol.py +222 -0
- lsurf/propagation/propagators/__init__.py +101 -0
- lsurf/propagation/propagators/detector_handler.py +354 -0
- lsurf/propagation/propagators/factory.py +200 -0
- lsurf/propagation/propagators/fresnel_handler.py +305 -0
- lsurf/propagation/propagators/gpu_gradient.py +566 -0
- lsurf/propagation/propagators/gpu_surface_propagator.py +707 -0
- lsurf/propagation/propagators/gradient.py +429 -0
- lsurf/propagation/propagators/intersection_handler.py +327 -0
- lsurf/propagation/propagators/material_propagator.py +398 -0
- lsurf/propagation/propagators/signed_distance_handler.py +522 -0
- lsurf/propagation/propagators/spectral_gpu_gradient.py +553 -0
- lsurf/propagation/propagators/surface_interaction.py +616 -0
- lsurf/propagation/propagators/surface_propagator.py +719 -0
- lsurf/py.typed +1 -0
- lsurf/simulation/__init__.py +70 -0
- lsurf/simulation/config.py +164 -0
- lsurf/simulation/orchestrator.py +462 -0
- lsurf/simulation/result.py +299 -0
- lsurf/simulation/simulation.py +262 -0
- lsurf/sources/__init__.py +128 -0
- lsurf/sources/base.py +264 -0
- lsurf/sources/collimated.py +252 -0
- lsurf/sources/custom.py +409 -0
- lsurf/sources/diverging.py +228 -0
- lsurf/sources/gaussian.py +272 -0
- lsurf/sources/parallel_from_positions.py +197 -0
- lsurf/sources/point.py +172 -0
- lsurf/sources/uniform_diverging.py +258 -0
- lsurf/surfaces/__init__.py +184 -0
- lsurf/surfaces/cpu/__init__.py +50 -0
- lsurf/surfaces/cpu/curved_wave.py +463 -0
- lsurf/surfaces/cpu/gerstner_wave.py +381 -0
- lsurf/surfaces/cpu/wave_params.py +118 -0
- lsurf/surfaces/gpu/__init__.py +72 -0
- lsurf/surfaces/gpu/annular_plane.py +453 -0
- lsurf/surfaces/gpu/bounded_plane.py +390 -0
- lsurf/surfaces/gpu/curved_wave.py +483 -0
- lsurf/surfaces/gpu/gerstner_wave.py +377 -0
- lsurf/surfaces/gpu/multi_curved_wave.py +520 -0
- lsurf/surfaces/gpu/plane.py +299 -0
- lsurf/surfaces/gpu/recording_sphere.py +587 -0
- lsurf/surfaces/gpu/sphere.py +311 -0
- lsurf/surfaces/protocol.py +336 -0
- lsurf/surfaces/registry.py +373 -0
- lsurf/utilities/__init__.py +175 -0
- lsurf/utilities/detector_analysis.py +814 -0
- lsurf/utilities/fresnel.py +628 -0
- lsurf/utilities/interactions.py +1215 -0
- lsurf/utilities/propagation.py +602 -0
- lsurf/utilities/ray_data.py +532 -0
- lsurf/utilities/recording_sphere.py +745 -0
- lsurf/utilities/time_spread.py +463 -0
- lsurf/visualization/__init__.py +329 -0
- lsurf/visualization/absorption_plots.py +334 -0
- lsurf/visualization/atmospheric_plots.py +754 -0
- lsurf/visualization/common.py +348 -0
- lsurf/visualization/detector_plots.py +1350 -0
- lsurf/visualization/detector_sphere_plots.py +1173 -0
- lsurf/visualization/fresnel_plots.py +1061 -0
- lsurf/visualization/ocean_simulation_plots.py +999 -0
- lsurf/visualization/polarization_plots.py +916 -0
- lsurf/visualization/raytracing_plots.py +1521 -0
- lsurf/visualization/ring_detector_plots.py +1867 -0
- lsurf/visualization/time_spread_plots.py +531 -0
- lsurf-1.0.0.dist-info/METADATA +381 -0
- lsurf-1.0.0.dist-info/RECORD +180 -0
- lsurf-1.0.0.dist-info/WHEEL +5 -0
- lsurf-1.0.0.dist-info/entry_points.txt +2 -0
- lsurf-1.0.0.dist-info/licenses/LICENSE +32 -0
- lsurf-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# The Clear BSD License
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2026 Tobias Heibges
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted (subject to the limitations in the disclaimer
|
|
8
|
+
# below) provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
#
|
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
|
16
|
+
#
|
|
17
|
+
# * Neither the name of the copyright holder nor the names of its
|
|
18
|
+
# contributors may be used to endorse or promote products derived from this
|
|
19
|
+
# software without specific prior written permission.
|
|
20
|
+
#
|
|
21
|
+
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
|
22
|
+
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
23
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
24
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
25
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
26
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
27
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
28
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
29
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
30
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
Materials Module
|
|
36
|
+
|
|
37
|
+
Provides optical material definitions with spatially-varying properties.
|
|
38
|
+
Supports homogeneous materials with constant properties and dispersion models.
|
|
39
|
+
|
|
40
|
+
Module Structure
|
|
41
|
+
----------------
|
|
42
|
+
- base/: Abstract base classes (MaterialField, HomogeneousMaterial, etc.)
|
|
43
|
+
- implementations/: Concrete material implementations
|
|
44
|
+
- utils/: Dispersion functions, factories, constants
|
|
45
|
+
|
|
46
|
+
Note: GPU propagation kernels are in lsurf.propagation.kernels.propagation
|
|
47
|
+
|
|
48
|
+
Classes
|
|
49
|
+
-------
|
|
50
|
+
MaterialField
|
|
51
|
+
Abstract base class for material property fields.
|
|
52
|
+
HomogeneousMaterial
|
|
53
|
+
Uniform material with constant optical properties.
|
|
54
|
+
SimpleInhomogeneousModel
|
|
55
|
+
Radially-symmetric inhomogeneous materials (GPU via LUT).
|
|
56
|
+
GridInhomogeneousModel
|
|
57
|
+
3D grid-based inhomogeneous materials (GPU via trilinear interp).
|
|
58
|
+
FullInhomogeneousModel
|
|
59
|
+
Arbitrary Python inhomogeneous materials (CPU-only).
|
|
60
|
+
|
|
61
|
+
Constants
|
|
62
|
+
---------
|
|
63
|
+
VACUUM
|
|
64
|
+
Perfect vacuum with n = 1.0.
|
|
65
|
+
AIR_STP
|
|
66
|
+
Air at standard temperature and pressure, n = 1.000293.
|
|
67
|
+
WATER
|
|
68
|
+
Pure water with n = 1.333 and absorption.
|
|
69
|
+
BK7_GLASS
|
|
70
|
+
Schott N-BK7 optical glass, n = 1.5168.
|
|
71
|
+
|
|
72
|
+
Functions
|
|
73
|
+
---------
|
|
74
|
+
sellmeier_refractive_index
|
|
75
|
+
Compute n using Sellmeier equation.
|
|
76
|
+
cauchy_refractive_index
|
|
77
|
+
Compute n using Cauchy equation.
|
|
78
|
+
create_sellmeier_material
|
|
79
|
+
Factory for Sellmeier-dispersion materials.
|
|
80
|
+
create_cauchy_material
|
|
81
|
+
Factory for Cauchy-dispersion materials.
|
|
82
|
+
|
|
83
|
+
Examples
|
|
84
|
+
--------
|
|
85
|
+
>>> from lsurf.materials import VACUUM, WATER, HomogeneousMaterial
|
|
86
|
+
>>>
|
|
87
|
+
>>> # Use pre-defined material
|
|
88
|
+
>>> n = WATER.get_refractive_index(0, 0, 0, 550e-9)
|
|
89
|
+
>>>
|
|
90
|
+
>>> # Create custom material
|
|
91
|
+
>>> oil = HomogeneousMaterial("Oil", 1.47, absorption_coef=0.01)
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
# Base classes
|
|
95
|
+
from .base import (
|
|
96
|
+
MaterialField,
|
|
97
|
+
HomogeneousMaterial,
|
|
98
|
+
SimpleInhomogeneousModel,
|
|
99
|
+
GridInhomogeneousModel,
|
|
100
|
+
FullInhomogeneousModel,
|
|
101
|
+
EARTH_RADIUS,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Standard material constants
|
|
105
|
+
from .implementations import (
|
|
106
|
+
VACUUM,
|
|
107
|
+
AIR_STP,
|
|
108
|
+
WATER,
|
|
109
|
+
BK7_GLASS,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Atmosphere implementations
|
|
113
|
+
from .implementations import (
|
|
114
|
+
ExponentialAtmosphere,
|
|
115
|
+
STANDARD_ATMOSPHERE,
|
|
116
|
+
create_exponential_atmosphere,
|
|
117
|
+
DuctAtmosphere,
|
|
118
|
+
create_duct_atmosphere,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Utilities
|
|
122
|
+
from .utils import (
|
|
123
|
+
# Constants
|
|
124
|
+
N_SEA_LEVEL,
|
|
125
|
+
SCALE_HEIGHT_DEFAULT,
|
|
126
|
+
# Dispersion functions
|
|
127
|
+
sellmeier_refractive_index,
|
|
128
|
+
cauchy_refractive_index,
|
|
129
|
+
# Factory functions
|
|
130
|
+
create_sellmeier_material,
|
|
131
|
+
create_cauchy_material,
|
|
132
|
+
# GPU device functions
|
|
133
|
+
device_sellmeier_equation,
|
|
134
|
+
device_cauchy_equation,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
__all__ = [
|
|
138
|
+
# Base classes
|
|
139
|
+
"MaterialField",
|
|
140
|
+
"HomogeneousMaterial",
|
|
141
|
+
# Inhomogeneous material base classes (template system)
|
|
142
|
+
"SimpleInhomogeneousModel",
|
|
143
|
+
"GridInhomogeneousModel",
|
|
144
|
+
"FullInhomogeneousModel",
|
|
145
|
+
# Standard materials
|
|
146
|
+
"VACUUM",
|
|
147
|
+
"AIR_STP",
|
|
148
|
+
"WATER",
|
|
149
|
+
"BK7_GLASS",
|
|
150
|
+
# Atmosphere materials
|
|
151
|
+
"ExponentialAtmosphere",
|
|
152
|
+
"STANDARD_ATMOSPHERE",
|
|
153
|
+
"create_exponential_atmosphere",
|
|
154
|
+
"DuctAtmosphere",
|
|
155
|
+
"create_duct_atmosphere",
|
|
156
|
+
# Atmosphere constants
|
|
157
|
+
"EARTH_RADIUS",
|
|
158
|
+
"N_SEA_LEVEL",
|
|
159
|
+
"SCALE_HEIGHT_DEFAULT",
|
|
160
|
+
# Dispersion functions
|
|
161
|
+
"sellmeier_refractive_index",
|
|
162
|
+
"cauchy_refractive_index",
|
|
163
|
+
# Factory functions
|
|
164
|
+
"create_sellmeier_material",
|
|
165
|
+
"create_cauchy_material",
|
|
166
|
+
# GPU device functions
|
|
167
|
+
"device_sellmeier_equation",
|
|
168
|
+
"device_cauchy_equation",
|
|
169
|
+
]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# The Clear BSD License
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2026 Tobias Heibges
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted (subject to the limitations in the disclaimer
|
|
8
|
+
# below) provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
#
|
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
|
16
|
+
#
|
|
17
|
+
# * Neither the name of the copyright holder nor the names of its
|
|
18
|
+
# contributors may be used to endorse or promote products derived from this
|
|
19
|
+
# software without specific prior written permission.
|
|
20
|
+
#
|
|
21
|
+
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
|
22
|
+
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
23
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
24
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
25
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
26
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
27
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
28
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
29
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
30
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
Base Classes for Materials Module
|
|
36
|
+
|
|
37
|
+
This submodule contains the abstract base classes and template classes
|
|
38
|
+
for the materials system:
|
|
39
|
+
|
|
40
|
+
- MaterialField: Abstract base class for all materials
|
|
41
|
+
- HomogeneousMaterial: Uniform material with constant optical properties
|
|
42
|
+
- SimpleInhomogeneousModel: Radially-symmetric 1D materials (GPU via LUT)
|
|
43
|
+
- SpectralInhomogeneousModel: Radially-symmetric 2D materials with wavelength
|
|
44
|
+
dependence (GPU via 2D LUT)
|
|
45
|
+
- GridInhomogeneousModel: 3D grid-based materials (GPU via trilinear interp)
|
|
46
|
+
- FullInhomogeneousModel: Arbitrary Python materials (CPU-only)
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
from .material_field import MaterialField
|
|
50
|
+
from .homogeneous import HomogeneousMaterial
|
|
51
|
+
from .simple_inhomogeneous import SimpleInhomogeneousModel, EARTH_RADIUS
|
|
52
|
+
from .spectral_inhomogeneous import SpectralInhomogeneousModel
|
|
53
|
+
from .grid_inhomogeneous import GridInhomogeneousModel
|
|
54
|
+
from .full_inhomogeneous import FullInhomogeneousModel
|
|
55
|
+
|
|
56
|
+
__all__ = [
|
|
57
|
+
"MaterialField",
|
|
58
|
+
"HomogeneousMaterial",
|
|
59
|
+
"SimpleInhomogeneousModel",
|
|
60
|
+
"SpectralInhomogeneousModel",
|
|
61
|
+
"GridInhomogeneousModel",
|
|
62
|
+
"FullInhomogeneousModel",
|
|
63
|
+
"EARTH_RADIUS",
|
|
64
|
+
]
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# The Clear BSD License
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2026 Tobias Heibges
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted (subject to the limitations in the disclaimer
|
|
8
|
+
# below) provided that the following conditions are met:
|
|
9
|
+
#
|
|
10
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
# this list of conditions and the following disclaimer.
|
|
12
|
+
#
|
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
14
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
|
16
|
+
#
|
|
17
|
+
# * Neither the name of the copyright holder nor the names of its
|
|
18
|
+
# contributors may be used to endorse or promote products derived from this
|
|
19
|
+
# software without specific prior written permission.
|
|
20
|
+
#
|
|
21
|
+
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
|
22
|
+
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
23
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
24
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
25
|
+
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
26
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
27
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
28
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
29
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
30
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
Full Inhomogeneous Model (CPU-only, Arbitrary Python)
|
|
36
|
+
|
|
37
|
+
Base class for arbitrary 3D inhomogeneous materials (CPU-only).
|
|
38
|
+
Use this when you need maximum flexibility and cannot express your model
|
|
39
|
+
using the other tiers. Any Python code is allowed.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
from abc import ABC, abstractmethod
|
|
43
|
+
|
|
44
|
+
import numpy as np
|
|
45
|
+
from numpy.typing import NDArray
|
|
46
|
+
|
|
47
|
+
from .material_field import MaterialField
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class FullInhomogeneousModel(MaterialField, ABC):
|
|
51
|
+
"""
|
|
52
|
+
Base class for arbitrary 3D inhomogeneous materials (CPU-only).
|
|
53
|
+
|
|
54
|
+
Use this when you need maximum flexibility and cannot express your model
|
|
55
|
+
using the other tiers. Any Python code is allowed, including external
|
|
56
|
+
libraries, database lookups, or complex computations.
|
|
57
|
+
|
|
58
|
+
GPU acceleration is not available for this tier. Use GradientPropagator
|
|
59
|
+
for CPU propagation.
|
|
60
|
+
|
|
61
|
+
User must implement:
|
|
62
|
+
- `get_refractive_index(x, y, z, wavelength)`
|
|
63
|
+
|
|
64
|
+
User may optionally implement:
|
|
65
|
+
- `get_refractive_index_gradient(x, y, z, wavelength)` (default: numerical)
|
|
66
|
+
|
|
67
|
+
Example
|
|
68
|
+
-------
|
|
69
|
+
>>> class WeatherModel(FullInhomogeneousModel):
|
|
70
|
+
... def __init__(self, weather_file):
|
|
71
|
+
... super().__init__(name="Weather Model")
|
|
72
|
+
... self._data = load_weather_data(weather_file)
|
|
73
|
+
...
|
|
74
|
+
... def get_refractive_index(self, x, y, z, wavelength):
|
|
75
|
+
... return self._data.interpolate(x, y, z)
|
|
76
|
+
...
|
|
77
|
+
>>> model = WeatherModel("weather.nc")
|
|
78
|
+
>>> propagator = GradientPropagator() # CPU only
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
def __init__(self, name: str = "Full Inhomogeneous"):
|
|
82
|
+
super().__init__(name)
|
|
83
|
+
self._is_homogeneous = False
|
|
84
|
+
|
|
85
|
+
@abstractmethod
|
|
86
|
+
def get_refractive_index(
|
|
87
|
+
self,
|
|
88
|
+
x: float | NDArray[np.float64],
|
|
89
|
+
y: float | NDArray[np.float64],
|
|
90
|
+
z: float | NDArray[np.float64],
|
|
91
|
+
wavelength: float | NDArray[np.float64],
|
|
92
|
+
) -> float | NDArray[np.float64]:
|
|
93
|
+
"""
|
|
94
|
+
Get refractive index at position.
|
|
95
|
+
|
|
96
|
+
Any Python code is allowed here.
|
|
97
|
+
|
|
98
|
+
Parameters
|
|
99
|
+
----------
|
|
100
|
+
x, y, z : float or ndarray
|
|
101
|
+
Position coordinates in meters
|
|
102
|
+
wavelength : float or ndarray
|
|
103
|
+
Wavelength in meters
|
|
104
|
+
|
|
105
|
+
Returns
|
|
106
|
+
-------
|
|
107
|
+
float or ndarray
|
|
108
|
+
Refractive index n >= 1.0
|
|
109
|
+
"""
|
|
110
|
+
pass
|
|
111
|
+
|
|
112
|
+
def get_refractive_index_gradient(
|
|
113
|
+
self,
|
|
114
|
+
x: float | NDArray[np.float64],
|
|
115
|
+
y: float | NDArray[np.float64],
|
|
116
|
+
z: float | NDArray[np.float64],
|
|
117
|
+
wavelength: float | NDArray[np.float64],
|
|
118
|
+
) -> tuple[
|
|
119
|
+
float | NDArray[np.float64],
|
|
120
|
+
float | NDArray[np.float64],
|
|
121
|
+
float | NDArray[np.float64],
|
|
122
|
+
]:
|
|
123
|
+
"""
|
|
124
|
+
Get gradient of n at position.
|
|
125
|
+
|
|
126
|
+
Default implementation uses numerical differentiation.
|
|
127
|
+
Override for analytical gradients.
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
x, y, z : float or ndarray
|
|
132
|
+
Position coordinates in meters
|
|
133
|
+
wavelength : float or ndarray
|
|
134
|
+
Wavelength in meters
|
|
135
|
+
|
|
136
|
+
Returns
|
|
137
|
+
-------
|
|
138
|
+
tuple
|
|
139
|
+
(dn/dx, dn/dy, dn/dz) in m^-1
|
|
140
|
+
"""
|
|
141
|
+
eps = 1.0 # 1 meter step
|
|
142
|
+
|
|
143
|
+
x = np.asarray(x)
|
|
144
|
+
y = np.asarray(y)
|
|
145
|
+
z = np.asarray(z)
|
|
146
|
+
|
|
147
|
+
n = self.get_refractive_index
|
|
148
|
+
|
|
149
|
+
grad_x = (n(x + eps, y, z, wavelength) - n(x - eps, y, z, wavelength)) / (
|
|
150
|
+
2 * eps
|
|
151
|
+
)
|
|
152
|
+
grad_y = (n(x, y + eps, z, wavelength) - n(x, y - eps, z, wavelength)) / (
|
|
153
|
+
2 * eps
|
|
154
|
+
)
|
|
155
|
+
grad_z = (n(x, y, z + eps, wavelength) - n(x, y, z - eps, wavelength)) / (
|
|
156
|
+
2 * eps
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
return grad_x, grad_y, grad_z
|
|
160
|
+
|
|
161
|
+
def get_absorption_coefficient(
|
|
162
|
+
self,
|
|
163
|
+
x: float | NDArray[np.float64],
|
|
164
|
+
y: float | NDArray[np.float64],
|
|
165
|
+
z: float | NDArray[np.float64],
|
|
166
|
+
wavelength: float | NDArray[np.float64],
|
|
167
|
+
) -> float | NDArray[np.float64]:
|
|
168
|
+
"""Return absorption coefficient (default: 0)."""
|
|
169
|
+
if isinstance(x, np.ndarray):
|
|
170
|
+
return np.zeros_like(x)
|
|
171
|
+
return 0.0
|
|
172
|
+
|
|
173
|
+
def get_scattering_coefficient(
|
|
174
|
+
self,
|
|
175
|
+
x: float | NDArray[np.float64],
|
|
176
|
+
y: float | NDArray[np.float64],
|
|
177
|
+
z: float | NDArray[np.float64],
|
|
178
|
+
wavelength: float | NDArray[np.float64],
|
|
179
|
+
) -> float | NDArray[np.float64]:
|
|
180
|
+
"""Return scattering coefficient (default: 0)."""
|
|
181
|
+
if isinstance(x, np.ndarray):
|
|
182
|
+
return np.zeros_like(x)
|
|
183
|
+
return 0.0
|
|
184
|
+
|
|
185
|
+
# =========================================================================
|
|
186
|
+
# GPU INTERFACE - NOT SUPPORTED
|
|
187
|
+
# =========================================================================
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def gpu_material_id(self) -> int:
|
|
191
|
+
"""GPU is not supported for FullInhomogeneousModel."""
|
|
192
|
+
raise NotImplementedError(
|
|
193
|
+
"FullInhomogeneousModel does not support GPU acceleration. "
|
|
194
|
+
"Use GradientPropagator for CPU propagation, or consider using "
|
|
195
|
+
"SimpleInhomogeneousModel or GridInhomogeneousModel for GPU support."
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
def get_gpu_kernels(self) -> dict:
|
|
199
|
+
"""GPU is not supported for FullInhomogeneousModel."""
|
|
200
|
+
raise NotImplementedError(
|
|
201
|
+
"FullInhomogeneousModel does not support GPU acceleration."
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
def get_gpu_parameters(self) -> tuple:
|
|
205
|
+
"""GPU is not supported for FullInhomogeneousModel."""
|
|
206
|
+
raise NotImplementedError(
|
|
207
|
+
"FullInhomogeneousModel does not support GPU acceleration."
|
|
208
|
+
)
|