Example 06: Detector Scan (Planar Surface)

Location: scripts/06_detector_scan.py

This example demonstrates scanning a detector through angular positions to measure ray distributions from a planar water surface.

Overview

Features demonstrated:

  • Detector position scanning

  • Time-of-arrival measurements

  • Angular distribution analysis

  • Specular reflection peak detection

  • Multi-panel visualization

Geometry

            Detector arc (0-90°)
            ○ ○ ○ ○ ○ ○ ○
           ○             ○
          ○               ○
         ○                 ○
Beam → ○  ═════════════════  ← Water surface (z=0)
      45°
  • Water surface: Horizontal plane at z=0

  • Beam: 45° grazing angle, 5 mm radius, 5000 rays

  • Detector: 2 cm radius sphere, scans 0-90° in 1° steps

Key Code Sections

Detector Scanning Loop

detector_angles_deg = np.arange(0, 91, 1)
detection_counts = np.zeros(len(detector_angles_deg))

for idx, angle_deg in enumerate(detector_angles_deg):
    angle_rad = np.radians(angle_deg)
    detector_pos = (
        detector_distance * np.cos(angle_rad),
        0,
        detector_distance * np.sin(angle_rad),
    )

    detector = sr.SphericalDetector(
        center=detector_pos,
        radius=detector_radius,
    )

    events = detector.detect(reflected_rays)
    detection_counts[idx] = len(events)

Timing Analysis

For each detection, record arrival time and angle:

if num_detected > 0:
    times = np.array([e.time for e in events])
    mean_arrival_times[idx] = np.mean(times)
    std_arrival_times[idx] = np.std(times)

    # Angles to detector normal
    detector_normal = -np.array(detector_pos) / np.linalg.norm(detector_pos)
    angles = []
    for e in events:
        ray_dir = e.direction / np.linalg.norm(e.direction)
        cos_angle = np.clip(np.dot(ray_dir, detector_normal), -1, 1)
        angles.append(np.degrees(np.arccos(cos_angle)))

Visualization

Two plots are generated:

  1. Ray paths (06_detector_scan_rays.png): - Incident and reflected ray paths - Surface geometry - Intersection points

  2. Detector scan results (06_detector_scan.png): - Detection count vs. angle - Intensity vs. angle - Mean arrival time vs. angle - Timing spread vs. angle - Angular distribution histograms - Time distribution histograms

Expected Output

Console output:

======================================================================
Detector Position Scan - Planar Water Surface
======================================================================

Planar Surface:
  Material: Water (n ≈ 1.33)
  Position: z = 0

Beam:
  Rays: 5000
  Grazing angle: 45°
  Radius: 5.0 mm
  Height: 5.0 cm

Detector:
  Distance: 100 cm
  Radius: 2.0 cm

Scanning 91 detector positions...

Results:
  Expected specular angle: 45°
  Peak detection: 5000 rays at 43°
  Total detections: 12,876
  Detection efficiency: 7.2%

Physics

Specular Reflection

For a planar surface, the law of reflection predicts:

\[\theta_r = \theta_i\]

where \(\theta_i\) is the incident angle and \(\theta_r\) is the reflection angle.

For a 45° grazing angle:

  • Incident angle to normal: 45°

  • Reflection angle to normal: 45°

  • Expected detector peak: 45° above horizon

Detection Efficiency

Only rays within the detector solid angle are recorded:

\[\Omega_{detector} = \frac{\pi r_{detector}^2}{d_{detector}^2}\]

For the parameters in this example:

  • \(r_{detector} = 0.02\) m

  • \(d_{detector} = 1.0\) m

  • \(\Omega \approx 0.0013\) sr (0.01% of sphere)

Time Spread

The timing spread arises from:

  1. Beam geometry: Rays start at different positions

  2. Path length variation: Different distances to detector

  3. Multiple reflections: (negligible for planar surface)

Running the Example

From the scripts/ directory:

python 06_detector_scan.py

Execution time: ~5 seconds (GPU) or ~20 seconds (CPU)

Generated plots:

  • plots/06_detector_scan_rays.png

  • plots/06_detector_scan.png

Exercises

  1. Vary beam angle: Change grazing_angle_deg to 30° or 60°

  2. Detector resolution: Reduce detector_step to 0.5° for finer sampling

  3. Larger detector: Increase detector_radius to 0.05 m

  4. Different materials: Replace water with BK7_GLASS

See Also