본문 바로가기
Camera

Lens PSF Complex Vectorial Field Data

by 이센 2025. 2. 10.

1. Complex Vectorial Field Data란?

  • 전자기 시뮬레이션에서는 복소수 벡터 필드(Complex Vectorial Field) 데이터를 사용하여 전자기파의 진폭(Amplitude)과 위상(Phase) 정보를 포함한 전기장(E-field) 분포를 정의할 수 있음.
  • CODE V에서는 zf.dat, zfPlus20.dat 형식으로 출력되며, 이를 EMW에서 사용자 정의 광원(Custom Source) 으로 활용 가능.

2. CODE V 없이 Complex Vectorial Field Data를 구하는 방법

CODE V 없이도 렌즈의 PSF 특성을 반영한 복소수 벡터 필드 데이터를 생성할 수 있다.

 

방법 1: Python 또는 MATLAB을 이용한 직접 계산 

렌즈의 회절 이론(Airy 패턴) 및 광학 전파 모델을 기반으로 복소수 벡터 필드를 생성

 

1-1. PSF를 기반으로 한 전기장(E-field) 계산

  • 렌즈의 회절 한계점(점광원 PSF) 및 위상 정보를 반영하여 회절 제한된 복소수 필드를 생성.
  • 회절 한계에서 PSF는 Airy 패턴으로 근사 가능:

E(r)=E02J1(kr)kreiϕE(r) = E_0 \frac{2 J_1(k r)}{k r} e^{i\phi}

  • J1J_1 : 1차 Bessel 함수
  • k=2πλk = \frac{2\pi}{\lambda} (파수)
  • rr : 중심에서의 거리
  • ϕ\phi : 위상 정보

방법 2: Fourier Optics 기반의 광학 시뮬레이션 사용

Python 또는 MATLAB에서 Fourier Transform을 사용하여 PSF를 생성

  • 렌즈의 광학 전파 모델(Propagation Model) 을 적용하여 Complex Field 생성 가능.
  • Angular Spectrum Method 또는 Fresnel Integral 을 사용하여 직접 계산.

Fourier Optics 기반 PSF 생성 및 Complex Field 변환

  1. 렌즈의 전방파면(Wavefront) 또는 Aperture Field를 설정
  2. Fourier Transform(푸리에 변환) 기반의 광 전파 시뮬레이션 수행
  3. 출력된 필드에서 복소수 벡터 필드를 추출

빛이 Chip 의 사선으로 들어오는 경우 Simulation 방법론

빛이 칩의 센터에서 수직으로 입사하는 경우에는 비교적 간단하게 회절 이론(Airy Pattern) 및 Fourier Optics을 활용하여 Complex Vectorial Field Data를 구할 수 있습니다.

하지만, 빛이 칩에 사선(Oblique Angle)으로 입사하는 경우, 광학계의 비대칭성 및 추가적인 위상 변화를 고려해야 하므로 보다 복잡한 방식이 필요합니다.

1. 사선 입사 시 추가적으로 고려해야 할 요소

  1. 회절 및 굴절 효과
    • 칩이 단순한 평판이 아니라면, 광학적 경계면에서의 굴절 및 반사(Rayleigh-Sommerfeld Integral, Fresnel Equations) 를 고려해야 함.
    • 굴절률이 다른 매질을 통과할 경우 Snell’s Law 적용 필요.
  2. 위상 변화
    • 빛이 사선으로 입사하면, 위상 분포가 기존의 축대칭 구조에서 벗어나고, 이는 위상 기울기(Phase Gradient) 로 반영됨.
    • Plane Wave Expansion (PWE) 또는 Angular Spectrum Method 를 활용하면 사선 입사에서의 위상 변화까지 반영 가능.
  3. Complex Field 계산 방식 변경 필요
    • 수직 입사에서는 원형 대칭(Airy Disk) 모델로 근사할 수 있지만,
      사선 입사에서는 비대칭적인 회절 패턴 및 위상 기울기 추가가 필요함.

 

3. 사선 입사  Complex Vectorial Field Data 얻는 방법

방법 1: Angular Spectrum Method 

Angular Spectrum Method(ASM)는 입사각을 가진 전자기파의 전파를 정확하게 계산하는 기법으로, 사선 입사에서 가장 적합한 방법 중 하나입니다.

Angular Spectrum Method를 활용한 Complex Field 계산

  1. 입사각(θ), 파장(λ) 및 칩 표면에서의 E-field 설정
  2. Fourier Transform을 사용하여 공간 주파수 도메인(Spatial Frequency Domain)으로 변환
  3. 위상 기울기(Phase Gradient)를 반영하여 사선 입사 구현
  4. Fourier 역변환(Inverse Fourier Transform)을 통해 실공간에서의 Complex Field 복원
import numpy as np
import matplotlib.pyplot as plt

# === [1] 기본 파라미터 설정 ===
wavelength = 550e-9  # 550 nm (녹색광)
k = 2 * np.pi / wavelength  # 파수 (wave number)
f_number = 1.8  # 렌즈의 F-number
sensor_size = 5.76e-3  # 이미지 센서 크기 (5.76mm x 4.29mm)
dx = 0.1e-6  # 공간 샘플링 (0.1μm, 고해상도)
z_propagation = 1e-6  # 센서 표면에서 1μm 위의 Complex Field 계산

# 0.8 Field Edge 위치 설정
field_positions = {
    "center": (0, 0, 0),  # (x, y, 입사각)
    "field_0.8": (0.8 * sensor_size / 2, 0, np.deg2rad(15))  # (x, y, 15도 입사)
}

# 해상도 설정 (고해상도 계산 후 3μm × 3μm 영역만 저장)
grid_size = 1024
x = np.linspace(-sensor_size/2, sensor_size/2, grid_size)
y = np.linspace(-sensor_size/2, sensor_size/2, grid_size)
X, Y = np.meshgrid(x, y)

# 공간 주파수 좌표 설정 (Fourier Transform을 위해)
fx = np.fft.fftfreq(grid_size, d=dx)
fy = np.fft.fftfreq(grid_size, d=dx)
FX, FY = np.meshgrid(fx, fy)

# === [2] Angular Spectrum Method 기반 전파 함수 정의 ===
def angular_spectrum_method(E0, theta, z):
    """ ASM을 이용한 광파 전파 시뮬레이션 (전파 필터 보정 포함) """
    # Fourier Transform -> 공간 주파수 영역으로 변환
    E0_spectrum = np.fft.fftshift(np.fft.fft2(np.fft.ifftshift(E0)))

    # 위상 기울기 추가 (사선 입사)
    kx = k * np.sin(theta)  # x 방향 위상 변화
    ky = 0  # y 방향은 고려하지 않음
    phase_tilt = np.exp(1j * (kx * X + ky * Y))

    # 전파 필터 (H(fx, fy))
    k_z_squared = 1 - (wavelength * FX)**2 - (wavelength * FY)**2
    k_z_squared[k_z_squared < 0] = 0  # 음수 값 방지 (전파되지 않는 영역 처리)
    H = np.exp(1j * k * z * np.sqrt(k_z_squared))  # 필터 적용

    # 필터 적용 후 역변환
    E_propagated_spectrum = E0_spectrum * H
    E_propagated = np.fft.ifftshift(np.fft.ifft2(np.fft.fftshift(E_propagated_spectrum)))

    return E_propagated * phase_tilt  # 사선 입사 보정 포함

# === [3] Chip Center & 0.8 Field Edge에서 Complex Field 생성 ===
complex_fields = {}
for position, (x0, y0, theta) in field_positions.items():
    # 초기 필드 설정 (Airy Disk 기반 PSF)
    R = np.sqrt((X - x0)**2 + (Y - y0)**2)
    E0 = (2 * np.sinc(k * R / np.pi))**2  # sinc 함수로 Airy Pattern 근사

    # Angular Spectrum Method로 전파
    E_complex = angular_spectrum_method(E0, theta, z_propagation)
    complex_fields[position] = E_complex

# === [4] 3μm × 3μm 범위의 데이터 추출 및 저장 ===
extract_size = int(3e-6 / dx)  # 3μm 크기에 맞는 인덱스 계산
center_idx = grid_size // 2  # 중심 인덱스
start_idx = center_idx - extract_size // 2
end_idx = center_idx + extract_size // 2

for position, field in complex_fields.items():
    # 3μm × 3μm 범위 추출
    field_extracted = field[start_idx:end_idx, start_idx:end_idx]

    # 실수부와 허수부 저장
    np.savetxt(f"{position}_real_asm_3um.dat", np.real(field_extracted), delimiter=",")
    np.savetxt(f"{position}_imag_asm_3um.dat", np.imag(field_extracted), delimiter=",")
    print(f"✅ {position}_real_asm_3um.dat, {position}_imag_asm_3um.dat 파일 저장 완료!")

# === [5] 결과 시각화 (3μm × 3μm 영역) ===
plt.figure(figsize=(10, 4))
for i, (position, field) in enumerate(complex_fields.items()):
    field_extracted = field[start_idx:end_idx, start_idx:end_idx]
    plt.subplot(1, 2, i + 1)
    plt.imshow(np.abs(field_extracted), cmap='hot', extent=[-1.5e-6, 1.5e-6, -1.5e-6, 1.5e-6])
    plt.title(f"Complex Field Amplitude ({position}) (3μm x 3μm)")
    plt.colorbar()
plt.show()