1+ # Setting the path for XLuminA modules:
2+ import os
3+ import sys
4+ current_path = os .path .abspath (os .path .join ('..' ))
5+ dir_path = os .path .dirname (current_path )
6+ module_path = os .path .join (dir_path )
7+ if module_path not in sys .path :
8+ sys .path .append (module_path )
9+
10+ from xlumina .__init__ import um , nm , cm , mm
11+ from xlumina .vectorized_optics import *
12+ from xlumina .optical_elements import hybrid_setup_sharp_focus
13+ from xlumina .loss_functions import vectorized_loss_hybrid
14+ from xlumina .toolbox import space , softmin
15+ import jax .numpy as jnp
16+
17+ """
18+ Large-scale setup for Dorn, Quabis and Leuchs (2004) benchmark rediscovery:
19+
20+ 3x3 initial setup - light gets detected across 6 detectors.
21+ """
22+
23+ # 1. System specs:
24+ sensor_lateral_size = 1024 # Resolution
25+ wavelength = 635 * nm
26+ x_total = 2500 * um
27+ x , y = space (x_total , sensor_lateral_size )
28+ shape = jnp .shape (x )[0 ]
29+
30+ # 2. Define the optical functions: two orthogonally polarized beams:
31+ w0 = (1200 * um , 1200 * um )
32+ ls1 = PolarizedLightSource (x , y , wavelength )
33+ ls1 .gaussian_beam (w0 = w0 , jones_vector = (1 , 1 ))
34+
35+ # 3. Define the output (High Resolution) detection:
36+ x_out , y_out = jnp .array (space (10 * um , 400 ))
37+
38+ # 4. High NA objective lens specs:
39+ NA = 0.9
40+ radius_lens = 3.6 * mm / 2
41+ f_lens = radius_lens / NA
42+
43+ # 5. Static parameters - don't change during optimization:
44+ fixed_params = [radius_lens , f_lens , x_out , y_out ]
45+
46+ # 6. Define the loss function:
47+ @jit
48+ def loss_hybrid_sharp_focus (parameters ):
49+ # Output from hybrid_setup is jnp.array(6, N, N): for 6 detectors
50+ detected_z_intensities , _ = hybrid_setup_sharp_focus (ls1 , ls1 , ls1 , ls1 , ls1 , ls1 , parameters , fixed_params )
51+
52+ # Get the minimum value within loss value array of shape (6, 1, 1)
53+ loss_val = softmin (vectorized_loss_hybrid (detected_z_intensities ))
54+
55+ return loss_val
0 commit comments