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
lsurf/__init__.py
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
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
|
+
L-SURF: Light Surface Reflections
|
|
36
|
+
|
|
37
|
+
A GPU-accelerated physically-accurate raytracing framework for simulating
|
|
38
|
+
light-surface interactions with spatially-varying material properties.
|
|
39
|
+
|
|
40
|
+
Note: Numba performance warnings about GPU under-utilization are suppressed
|
|
41
|
+
by default. These warnings occur with small ray counts during testing but
|
|
42
|
+
are not relevant for production simulations with larger ray counts.
|
|
43
|
+
|
|
44
|
+
This module supports:
|
|
45
|
+
- Inhomogeneous media with gradient refractive indices
|
|
46
|
+
- Multiple scattering and subsurface propagation
|
|
47
|
+
- Fresnel reflection and refraction
|
|
48
|
+
- Wavelength-dependent material properties
|
|
49
|
+
- Polarization tracking (optional)
|
|
50
|
+
|
|
51
|
+
Main Components
|
|
52
|
+
---------------
|
|
53
|
+
- materials: Material property definitions (refractive index, absorption, etc.)
|
|
54
|
+
- surfaces: Surface geometry and intersection (planar, spherical, waves)
|
|
55
|
+
- sources: Ray generation (point, collimated, diverging, gaussian)
|
|
56
|
+
- detectors: Detection and analysis (spherical, planar, directional)
|
|
57
|
+
- ray_data: Ray batch data structures for GPU processing
|
|
58
|
+
- propagation: Ray propagation engine (straight-line and curved paths)
|
|
59
|
+
- gpu: GPU-accelerated kernels and algorithms
|
|
60
|
+
|
|
61
|
+
Example Usage
|
|
62
|
+
-------------
|
|
63
|
+
>>> from surface_roughness import materials, ray_data, propagation
|
|
64
|
+
>>>
|
|
65
|
+
>>> # Create material
|
|
66
|
+
>>> material = materials.AIR_STP
|
|
67
|
+
>>>
|
|
68
|
+
>>> # Create ray batch
|
|
69
|
+
>>> rays = ray_data.create_ray_batch(num_rays=10000)
|
|
70
|
+
>>>
|
|
71
|
+
>>> # Initialize rays (would come from source module)
|
|
72
|
+
>>> rays.positions[:] = ...
|
|
73
|
+
>>> rays.directions[:] = ...
|
|
74
|
+
>>> rays.active[:] = True
|
|
75
|
+
>>>
|
|
76
|
+
>>> # Propagate
|
|
77
|
+
>>> propagator = propagation.StraightLinePropagator()
|
|
78
|
+
>>> propagator.propagate_step(rays, step_size=1e-3, material=material)
|
|
79
|
+
|
|
80
|
+
Refactored Modules (New Structure)
|
|
81
|
+
----------------------------------
|
|
82
|
+
The codebase has been refactored into single-responsibility modules:
|
|
83
|
+
|
|
84
|
+
>>> # Modular surfaces
|
|
85
|
+
>>> from lsurf.surfaces import CurvedWaveSurface, PlaneSurface
|
|
86
|
+
>>>
|
|
87
|
+
>>> # Modular sources
|
|
88
|
+
>>> from surface_roughness.sources import CollimatedBeam, PointSource
|
|
89
|
+
>>>
|
|
90
|
+
>>> # Modular detectors
|
|
91
|
+
>>> from surface_roughness.detectors import SphericalDetector
|
|
92
|
+
>>>
|
|
93
|
+
>>> # Modular materials
|
|
94
|
+
>>> from surface_roughness.materials import WATER, create_sellmeier_material
|
|
95
|
+
|
|
96
|
+
References
|
|
97
|
+
----------
|
|
98
|
+
.. [1] Born, M., & Wolf, E. (1999). Principles of Optics (7th ed.).
|
|
99
|
+
Cambridge University Press.
|
|
100
|
+
.. [2] Ishimaru, A. (1978). Wave Propagation and Scattering in Random Media.
|
|
101
|
+
Academic Press.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
# =============================================================================
|
|
105
|
+
# Suppress Numba Performance Warnings
|
|
106
|
+
# =============================================================================
|
|
107
|
+
# These warnings about GPU under-utilization are expected for small test cases
|
|
108
|
+
# and are not relevant for production simulations with larger ray counts.
|
|
109
|
+
import warnings
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
from numba.core.errors import NumbaPerformanceWarning
|
|
113
|
+
|
|
114
|
+
warnings.filterwarnings("ignore", category=NumbaPerformanceWarning)
|
|
115
|
+
except ImportError:
|
|
116
|
+
# Numba not installed, no warnings to suppress
|
|
117
|
+
pass
|
|
118
|
+
|
|
119
|
+
# =============================================================================
|
|
120
|
+
# Module Imports (Refactored Structure)
|
|
121
|
+
# =============================================================================
|
|
122
|
+
# Refactored modules (new single-responsibility structure)
|
|
123
|
+
from . import detectors, materials, sources, surfaces, utilities
|
|
124
|
+
|
|
125
|
+
# Backward compatibility aliases for moved modules
|
|
126
|
+
ray_data = utilities.ray_data
|
|
127
|
+
propagation = utilities.propagation
|
|
128
|
+
fresnel = utilities.fresnel
|
|
129
|
+
recording_sphere = utilities.recording_sphere
|
|
130
|
+
|
|
131
|
+
# Supporting modules
|
|
132
|
+
from . import visualization
|
|
133
|
+
|
|
134
|
+
# Backward compatibility alias for moved interactions module
|
|
135
|
+
interactions = utilities.interactions
|
|
136
|
+
|
|
137
|
+
# Key visualization functions
|
|
138
|
+
from .visualization import (
|
|
139
|
+
create_beam_profile_figure,
|
|
140
|
+
create_detector_scan_figure,
|
|
141
|
+
create_ray_overview_figure,
|
|
142
|
+
create_wavelength_figure,
|
|
143
|
+
# Detector visualization
|
|
144
|
+
plot_beam_slice,
|
|
145
|
+
plot_bounce_points,
|
|
146
|
+
plot_detection_counts,
|
|
147
|
+
plot_detection_efficiency,
|
|
148
|
+
plot_mean_arrival_time,
|
|
149
|
+
plot_ray_endpoints_histogram,
|
|
150
|
+
plot_ray_endpoints_scatter,
|
|
151
|
+
# Ray tracing visualization
|
|
152
|
+
plot_ray_paths_projection,
|
|
153
|
+
plot_surface_profile,
|
|
154
|
+
plot_wavelength_histogram,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# Version info
|
|
158
|
+
__version__ = "0.2.0" # Refactored modular architecture
|
|
159
|
+
__author__ = "L-SURF Development Team"
|
|
160
|
+
|
|
161
|
+
# =============================================================================
|
|
162
|
+
# Expose key classes from refactored modules
|
|
163
|
+
# =============================================================================
|
|
164
|
+
|
|
165
|
+
# Materials module
|
|
166
|
+
# Analysis module
|
|
167
|
+
from . import analysis
|
|
168
|
+
|
|
169
|
+
# Detectors module
|
|
170
|
+
from .detectors import (
|
|
171
|
+
DetectionEvent,
|
|
172
|
+
Detector,
|
|
173
|
+
DirectionalDetector,
|
|
174
|
+
LocalRecordingSphere,
|
|
175
|
+
LocalRecordingSphereDetector,
|
|
176
|
+
PlanarDetector,
|
|
177
|
+
RecordingSphere,
|
|
178
|
+
# Recording sphere detectors
|
|
179
|
+
RecordingSphereBase,
|
|
180
|
+
RecordingSphereDetector,
|
|
181
|
+
SphericalDetector,
|
|
182
|
+
compute_angular_distribution,
|
|
183
|
+
compute_intensity_distribution,
|
|
184
|
+
compute_time_distribution,
|
|
185
|
+
compute_wavelength_distribution,
|
|
186
|
+
)
|
|
187
|
+
from .detectors import (
|
|
188
|
+
compute_statistics as compute_detector_statistics,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# Interactions
|
|
192
|
+
from .utilities.interactions import (
|
|
193
|
+
process_surface_interaction,
|
|
194
|
+
reflect_rays,
|
|
195
|
+
refract_rays,
|
|
196
|
+
trace_rays_multi_bounce,
|
|
197
|
+
trace_rays_with_splitting,
|
|
198
|
+
)
|
|
199
|
+
from .materials import (
|
|
200
|
+
AIR_STP,
|
|
201
|
+
BK7_GLASS,
|
|
202
|
+
VACUUM,
|
|
203
|
+
WATER,
|
|
204
|
+
HomogeneousMaterial,
|
|
205
|
+
MaterialField,
|
|
206
|
+
cauchy_refractive_index,
|
|
207
|
+
create_cauchy_material,
|
|
208
|
+
create_sellmeier_material,
|
|
209
|
+
sellmeier_refractive_index,
|
|
210
|
+
# Atmosphere materials
|
|
211
|
+
ExponentialAtmosphere,
|
|
212
|
+
STANDARD_ATMOSPHERE,
|
|
213
|
+
create_exponential_atmosphere,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
# Sources module
|
|
217
|
+
from .sources import (
|
|
218
|
+
CollimatedBeam,
|
|
219
|
+
DivergingBeam,
|
|
220
|
+
GaussianBeam,
|
|
221
|
+
ParallelBeamFromPositions,
|
|
222
|
+
PointSource,
|
|
223
|
+
RaySource,
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# Surfaces module
|
|
227
|
+
from .surfaces import (
|
|
228
|
+
EARTH_RADIUS,
|
|
229
|
+
CurvedWaveSurface,
|
|
230
|
+
GerstnerWaveParams,
|
|
231
|
+
GerstnerWaveSurface,
|
|
232
|
+
PlaneSurface,
|
|
233
|
+
SphereSurface,
|
|
234
|
+
RecordingSphereSurface,
|
|
235
|
+
LocalRecordingSphereSurface,
|
|
236
|
+
Surface,
|
|
237
|
+
SurfaceRole,
|
|
238
|
+
# Surface type registry
|
|
239
|
+
SurfaceTypeInfo,
|
|
240
|
+
register_surface_type,
|
|
241
|
+
get_surface_type,
|
|
242
|
+
get_surface_type_id,
|
|
243
|
+
is_gpu_capable,
|
|
244
|
+
list_surface_types,
|
|
245
|
+
# Backwards compatibility
|
|
246
|
+
GeometryInfo,
|
|
247
|
+
register_geometry,
|
|
248
|
+
get_geometry_id,
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
# Backwards compatibility alias
|
|
252
|
+
PlanarSurface = PlaneSurface
|
|
253
|
+
|
|
254
|
+
# Propagation
|
|
255
|
+
from .utilities.propagation import (
|
|
256
|
+
PropagationConfig,
|
|
257
|
+
PropagationMode,
|
|
258
|
+
StraightLinePropagator,
|
|
259
|
+
)
|
|
260
|
+
from .propagation import (
|
|
261
|
+
GPUGradientPropagator,
|
|
262
|
+
GPUInhomogeneousPropagator,
|
|
263
|
+
GPUMaterialID,
|
|
264
|
+
GradientPropagator,
|
|
265
|
+
create_propagator,
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# Ray data structures
|
|
269
|
+
from .utilities.ray_data import (
|
|
270
|
+
RayBatch,
|
|
271
|
+
RayStatistics,
|
|
272
|
+
compute_statistics,
|
|
273
|
+
create_ray_batch,
|
|
274
|
+
merge_ray_batches,
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
# Recording data and I/O from utilities
|
|
278
|
+
from .utilities.recording_sphere import (
|
|
279
|
+
RecordedRays,
|
|
280
|
+
load_recorded_rays_hdf5,
|
|
281
|
+
load_recorded_rays_numpy,
|
|
282
|
+
save_recorded_rays_hdf5,
|
|
283
|
+
save_recorded_rays_numpy,
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
__all__: list[str] = [
|
|
287
|
+
# ==========================================================================
|
|
288
|
+
# Refactored Modules
|
|
289
|
+
# ==========================================================================
|
|
290
|
+
"materials",
|
|
291
|
+
"ray_data",
|
|
292
|
+
"propagation",
|
|
293
|
+
"sources",
|
|
294
|
+
"surfaces",
|
|
295
|
+
"fresnel",
|
|
296
|
+
"interactions",
|
|
297
|
+
"visualization",
|
|
298
|
+
"detectors",
|
|
299
|
+
"recording_sphere",
|
|
300
|
+
"analysis",
|
|
301
|
+
# Material classes
|
|
302
|
+
"MaterialField",
|
|
303
|
+
"HomogeneousMaterial",
|
|
304
|
+
"VACUUM",
|
|
305
|
+
"AIR_STP",
|
|
306
|
+
"WATER",
|
|
307
|
+
"BK7_GLASS",
|
|
308
|
+
"sellmeier_refractive_index",
|
|
309
|
+
"cauchy_refractive_index",
|
|
310
|
+
"create_sellmeier_material",
|
|
311
|
+
"create_cauchy_material",
|
|
312
|
+
# Ray data structures
|
|
313
|
+
"RayBatch",
|
|
314
|
+
"RayStatistics",
|
|
315
|
+
"create_ray_batch",
|
|
316
|
+
"compute_statistics",
|
|
317
|
+
"merge_ray_batches",
|
|
318
|
+
# Propagation
|
|
319
|
+
"PropagationMode",
|
|
320
|
+
"PropagationConfig",
|
|
321
|
+
"StraightLinePropagator",
|
|
322
|
+
"GradientPropagator",
|
|
323
|
+
"GPUGradientPropagator",
|
|
324
|
+
"GPUInhomogeneousPropagator",
|
|
325
|
+
"GPUMaterialID",
|
|
326
|
+
"create_propagator",
|
|
327
|
+
# Sources
|
|
328
|
+
"RaySource",
|
|
329
|
+
"PointSource",
|
|
330
|
+
"CollimatedBeam",
|
|
331
|
+
"DivergingBeam",
|
|
332
|
+
"GaussianBeam",
|
|
333
|
+
"ParallelBeamFromPositions",
|
|
334
|
+
# Surfaces
|
|
335
|
+
"Surface",
|
|
336
|
+
"SurfaceRole",
|
|
337
|
+
"SurfaceTypeInfo",
|
|
338
|
+
"register_surface_type",
|
|
339
|
+
"get_surface_type",
|
|
340
|
+
"get_surface_type_id",
|
|
341
|
+
"is_gpu_capable",
|
|
342
|
+
"list_surface_types",
|
|
343
|
+
# Backwards compatibility
|
|
344
|
+
"GeometryInfo",
|
|
345
|
+
"register_geometry",
|
|
346
|
+
"get_geometry_id",
|
|
347
|
+
"PlaneSurface",
|
|
348
|
+
"PlanarSurface", # Backwards compatibility alias
|
|
349
|
+
"SphereSurface",
|
|
350
|
+
"RecordingSphereSurface",
|
|
351
|
+
"LocalRecordingSphereSurface",
|
|
352
|
+
"GerstnerWaveSurface",
|
|
353
|
+
"GerstnerWaveParams",
|
|
354
|
+
"CurvedWaveSurface",
|
|
355
|
+
"EARTH_RADIUS",
|
|
356
|
+
# Interactions
|
|
357
|
+
"process_surface_interaction",
|
|
358
|
+
"reflect_rays",
|
|
359
|
+
"refract_rays",
|
|
360
|
+
"trace_rays_multi_bounce",
|
|
361
|
+
"trace_rays_with_splitting",
|
|
362
|
+
# Detectors
|
|
363
|
+
"Detector",
|
|
364
|
+
"SphericalDetector",
|
|
365
|
+
"PlanarDetector",
|
|
366
|
+
"DirectionalDetector",
|
|
367
|
+
"DetectionEvent",
|
|
368
|
+
"compute_angular_distribution",
|
|
369
|
+
"compute_time_distribution",
|
|
370
|
+
"compute_intensity_distribution",
|
|
371
|
+
"compute_wavelength_distribution",
|
|
372
|
+
"compute_detector_statistics",
|
|
373
|
+
# Recording sphere detectors
|
|
374
|
+
"RecordingSphereBase",
|
|
375
|
+
"RecordingSphereDetector",
|
|
376
|
+
"LocalRecordingSphereDetector",
|
|
377
|
+
"RecordingSphere",
|
|
378
|
+
"LocalRecordingSphere",
|
|
379
|
+
"RecordedRays",
|
|
380
|
+
"save_recorded_rays_hdf5",
|
|
381
|
+
"load_recorded_rays_hdf5",
|
|
382
|
+
"save_recorded_rays_numpy",
|
|
383
|
+
"load_recorded_rays_numpy",
|
|
384
|
+
# Visualization
|
|
385
|
+
"plot_ray_paths_projection",
|
|
386
|
+
"plot_ray_endpoints_scatter",
|
|
387
|
+
"plot_ray_endpoints_histogram",
|
|
388
|
+
"plot_surface_profile",
|
|
389
|
+
"plot_bounce_points",
|
|
390
|
+
"create_ray_overview_figure",
|
|
391
|
+
"plot_beam_slice",
|
|
392
|
+
"plot_wavelength_histogram",
|
|
393
|
+
"plot_detection_counts",
|
|
394
|
+
"plot_detection_efficiency",
|
|
395
|
+
"plot_mean_arrival_time",
|
|
396
|
+
"create_wavelength_figure",
|
|
397
|
+
"create_beam_profile_figure",
|
|
398
|
+
"create_detector_scan_figure",
|
|
399
|
+
# Logging
|
|
400
|
+
"configure_logging",
|
|
401
|
+
]
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
# =============================================================================
|
|
405
|
+
# Logging Configuration
|
|
406
|
+
# =============================================================================
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
def configure_logging(
|
|
410
|
+
level: str = "INFO",
|
|
411
|
+
format: str = "%(levelname)s - %(message)s",
|
|
412
|
+
suppress_numba: bool = True,
|
|
413
|
+
) -> None:
|
|
414
|
+
"""
|
|
415
|
+
Configure logging for lsurf simulations.
|
|
416
|
+
|
|
417
|
+
Parameters
|
|
418
|
+
----------
|
|
419
|
+
level : str
|
|
420
|
+
Logging level: "DEBUG", "INFO", "WARNING", "ERROR".
|
|
421
|
+
DEBUG shows per-bounce details, INFO shows simulation summaries.
|
|
422
|
+
format : str
|
|
423
|
+
Log message format string.
|
|
424
|
+
suppress_numba : bool
|
|
425
|
+
If True, suppress verbose numba/CUDA logging and performance warnings
|
|
426
|
+
(default True). Set to False to see GPU under-utilization warnings
|
|
427
|
+
which can help optimize ray counts.
|
|
428
|
+
|
|
429
|
+
Examples
|
|
430
|
+
--------
|
|
431
|
+
>>> import lsurf as sr
|
|
432
|
+
>>> sr.configure_logging("INFO") # Show simulation progress
|
|
433
|
+
>>> sr.configure_logging("DEBUG") # Show detailed per-bounce info
|
|
434
|
+
>>> sr.configure_logging("INFO", suppress_numba=False) # Show GPU warnings
|
|
435
|
+
"""
|
|
436
|
+
import logging
|
|
437
|
+
import warnings
|
|
438
|
+
|
|
439
|
+
# Configure lsurf logger
|
|
440
|
+
lsurf_logger = logging.getLogger("lsurf")
|
|
441
|
+
lsurf_logger.setLevel(getattr(logging, level.upper()))
|
|
442
|
+
|
|
443
|
+
# Add handler if none exists
|
|
444
|
+
if not lsurf_logger.handlers:
|
|
445
|
+
handler = logging.StreamHandler()
|
|
446
|
+
handler.setFormatter(logging.Formatter(format))
|
|
447
|
+
lsurf_logger.addHandler(handler)
|
|
448
|
+
else:
|
|
449
|
+
# Update existing handler format
|
|
450
|
+
for handler in lsurf_logger.handlers:
|
|
451
|
+
handler.setFormatter(logging.Formatter(format))
|
|
452
|
+
|
|
453
|
+
# Handle numba loggers and warnings
|
|
454
|
+
if suppress_numba:
|
|
455
|
+
for name in ["numba", "numba.cuda"]:
|
|
456
|
+
logging.getLogger(name).setLevel(logging.WARNING)
|
|
457
|
+
# Suppress numba performance warnings (already done at import, but ensure)
|
|
458
|
+
try:
|
|
459
|
+
from numba.core.errors import NumbaPerformanceWarning
|
|
460
|
+
|
|
461
|
+
warnings.filterwarnings("ignore", category=NumbaPerformanceWarning)
|
|
462
|
+
except ImportError:
|
|
463
|
+
pass
|
|
464
|
+
else:
|
|
465
|
+
# Re-enable numba performance warnings if user wants them
|
|
466
|
+
try:
|
|
467
|
+
from numba.core.errors import NumbaPerformanceWarning
|
|
468
|
+
|
|
469
|
+
warnings.filterwarnings("default", category=NumbaPerformanceWarning)
|
|
470
|
+
except ImportError:
|
|
471
|
+
pass
|
|
@@ -0,0 +1,107 @@
|
|
|
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
|
+
Analysis Module - Sphere Pattern Analysis and Visualization
|
|
36
|
+
|
|
37
|
+
This module provides tools for analyzing ray patterns on spherical detection surfaces,
|
|
38
|
+
including HEALPix mapping, intensity distribution analysis, and arrival time statistics.
|
|
39
|
+
|
|
40
|
+
Available Functions
|
|
41
|
+
-------------------
|
|
42
|
+
rays_to_healpix
|
|
43
|
+
Convert recorded rays to HEALPix pixel representation
|
|
44
|
+
aggregate_healpix_data
|
|
45
|
+
Aggregate ray properties per HEALPix pixel
|
|
46
|
+
identify_peak_region
|
|
47
|
+
Find pixels with highest intensity
|
|
48
|
+
compute_time_statistics
|
|
49
|
+
Compute arrival time statistics in peak region
|
|
50
|
+
|
|
51
|
+
plot_mollweide_intensity
|
|
52
|
+
Visualize intensity distribution on Mollweide projection
|
|
53
|
+
plot_mollweide_time
|
|
54
|
+
Visualize arrival time distribution on Mollweide projection
|
|
55
|
+
plot_time_distributions
|
|
56
|
+
Plot arrival time histograms and statistics
|
|
57
|
+
plot_combined_analysis
|
|
58
|
+
Create comprehensive multi-panel figure
|
|
59
|
+
|
|
60
|
+
Examples
|
|
61
|
+
--------
|
|
62
|
+
>>> from lsurf import load_recorded_rays_hdf5
|
|
63
|
+
>>> from lsurf.analysis import rays_to_healpix, plot_mollweide_intensity
|
|
64
|
+
>>>
|
|
65
|
+
>>> # Load simulation data
|
|
66
|
+
>>> rays, metadata = load_recorded_rays_hdf5('simulation.h5')
|
|
67
|
+
>>>
|
|
68
|
+
>>> # Convert to HEALPix
|
|
69
|
+
>>> healpix_data = rays_to_healpix(rays, nside=128)
|
|
70
|
+
>>>
|
|
71
|
+
>>> # Visualize
|
|
72
|
+
>>> plot_mollweide_intensity(healpix_data, output='intensity_map.png')
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
from .healpix_utils import (
|
|
76
|
+
aggregate_healpix_data,
|
|
77
|
+
compute_time_statistics,
|
|
78
|
+
identify_peak_region,
|
|
79
|
+
rays_to_healpix,
|
|
80
|
+
)
|
|
81
|
+
from .sphere_viz import (
|
|
82
|
+
plot_2d_combined,
|
|
83
|
+
plot_2d_intensity,
|
|
84
|
+
plot_2d_time,
|
|
85
|
+
plot_combined_analysis,
|
|
86
|
+
plot_mollweide_intensity,
|
|
87
|
+
plot_mollweide_time,
|
|
88
|
+
plot_ray_direction_intensity,
|
|
89
|
+
plot_time_distributions,
|
|
90
|
+
plot_viewing_angle_intensity,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
__all__ = [
|
|
94
|
+
"rays_to_healpix",
|
|
95
|
+
"aggregate_healpix_data",
|
|
96
|
+
"identify_peak_region",
|
|
97
|
+
"compute_time_statistics",
|
|
98
|
+
"plot_mollweide_intensity",
|
|
99
|
+
"plot_mollweide_time",
|
|
100
|
+
"plot_time_distributions",
|
|
101
|
+
"plot_combined_analysis",
|
|
102
|
+
"plot_2d_intensity",
|
|
103
|
+
"plot_2d_time",
|
|
104
|
+
"plot_2d_combined",
|
|
105
|
+
"plot_viewing_angle_intensity",
|
|
106
|
+
"plot_ray_direction_intensity",
|
|
107
|
+
]
|