AIDT 온디바이스 STEM 방사광/단결정 X선 라우에 회절(Laue Diffraction) 격자 오리엔테이션 및 오일러 각 인덱싱 서보 제어기

연속 백색 X선 브래그 반사 패턴 gnomonic 투영, 고니오미터 3축 오일러 각도 서브-초 미세 정렬, 10,000Hz C# 엔진

1. 개요

단결정 실리콘 웨이퍼, 갈륨비소(GaAs), 초전도체 및 단백질 결정 구조 분석에서 단결정의 결정축 방향(Crystallographic Orientation)을 규명하는 가장 강력한 기법은 연속 스펙트럼의 백색 X선(White Beam)을 조사하는 라우에 회절(Laue Diffraction)입니다. 고정된 시료 내의 수많은 격자면(\(hkl\))은 브래그 조건(\(2d_{hkl}\sin\theta = \lambda\))을 만족하는 고유한 파장의 X선을 선택적으로 반사하여 2차원 평면 검출기에 일련의 타원형 존 축(Zone Axis) 라우에 스폿 패턴을 형성합니다. 그러나 임의로 거치된 결정 시료의 라우에 패턴을 자동 인덱싱(Indexing)하고 노모닉(Gnomonic) 투영을 통해 역격자 기저 벡터와 3차원 오일러 각(\(\phi, \theta, \psi\))을 산출한 뒤, 3축 고니오미터(Goniometer)를 서브-각초(< 0.001°) 정밀도로 구동하여 원하는 결정축(예: [001])을 X선 광축과 일치시키는 작업은 방대한 행렬 연산을 요구합니다. 본 고에서는 회절 스폿 좌표를 10,000Hz 주기로 추적하여 Busing-Levy UB 행렬을 갱신하는 0-Alloc C# 엔진을 구현합니다.

2. 수학적 모델링 및 지배 방정식

백색 X선 라우에 회절의 탄성 산란 파동벡터 및 역격자 벡터 관계식은 다음과 같습니다:

\[ \vec{q}_{lab} = \vec{k}_{out} - \vec{k}_{in} = \frac{2\pi}{\lambda_{cont}} (\hat{s}_{out} - \hat{s}_{in}) = \mathbf{U} \mathbf{B} \begin{pmatrix} h \\ k \\ l \end{pmatrix} \]

검출기 상의 스폿 위치 \((x_d, y_d)\)에 대한 노모닉(Gnomonic) 투영 및 단위 법선 벡터 변환식은 다음과 같습니다:

\[ \tan(2\theta) = \frac{\sqrt{x_d^2 + y_d^2}}{D_{det}}, \quad \cos(2\theta) = \hat{s}_{in} \cdot \hat{s}_{out}, \quad \hat{n}_{hkl} = \frac{\hat{s}_{out} - \hat{s}_{in}}{\|\hat{s}_{out} - \hat{s}_{in}\|} \]

결정 오리엔테이션 직교 행렬 \(\mathbf{U}\)와 오일러 각(\(\phi, \theta, \psi\))의 분해식은 다음과 같습니다:

\[ \mathbf{U}(\phi, \theta, \psi) = \mathbf{R}_z(\phi) \mathbf{R}_y(\theta) \mathbf{R}_x(\psi) \implies \vec{q}_{target} = \mathbf{U}_{target} \mathbf{B} \vec{h}_{zone} \]

현재 결정축과 목표 빔라인 축 간의 오정렬 각오차 영점화를 위한 고니오미터 3축 구동 제어식은 다음과 같습니다:

\[ \vec{\omega}_{gonio}^{cmd} = \mathbf{J}_{Euler}^{-1}(\vec{\theta}) \left( K_p (\hat{c}_{current} \times \hat{c}_{target}) + K_d \frac{d}{dt}(\hat{c}_{current} \times \hat{c}_{target}) \right) \]

3. 실시간 C# 서보 제어기 구현

다음은 고속 픽셀 검출기(Timepix)의 라우에 반사점 중심 좌표를 10,000Hz 주기로 수신하여 3축 피에조 고니오미터 각도 지령을 생성하는 0-Alloc C# 엔진 구현체입니다:

LaueCrystalIndexingServoEngine.cs
using System;
using System.Runtime.CompilerServices;

namespace ZeliDesk.Stem.LaueDiffraction
{
    public readonly ref struct LaueSpotFrame
    {
        public readonly double PrimarySpotXmm;
        public readonly double PrimarySpotYmm;
        public readonly double SecondarySpotXmm;
        public readonly double SecondarySpotYmm;
        public readonly double DetectorDistanceMm;

        public LaueSpotFrame(
            double primarySpotXmm,
            double primarySpotYmm,
            double secondarySpotXmm,
            double secondarySpotYmm,
            double detectorDistanceMm)
        {
            PrimarySpotXmm = primarySpotXmm;
            PrimarySpotYmm = primarySpotYmm;
            SecondarySpotXmm = secondarySpotXmm;
            SecondarySpotYmm = secondarySpotYmm;
            DetectorDistanceMm = detectorDistanceMm;
        }
    }

    public ref struct GoniometerControlCommand
    {
        public double RotationPhiDeg;
        public double RotationThetaDeg;
        public double RotationPsiDeg;
        public double MisalignmentErrorArcSec;
        public bool IsCrystalOriented;
        public bool IsPatternIndexed;
    }

    public ref struct LaueCrystalIndexingServoEngine
    {
        private readonly double _kp;
        private readonly double _kd;
        private readonly double _dt;
        private double _prevErrorRad;

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LaueCrystalIndexingServoEngine(double kp, double kd, double dt)
        {
            _kp = kp;
            _kd = kd;
            _dt = dt;
            _prevErrorRad = 0.0;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void ComputeOrientationServo(in LaueSpotFrame frame, out GoniometerControlCommand cmd)
        {
            cmd = default;
            // Angle calculation from primary spot offset
            double rPrimary = Math.Sqrt(frame.PrimarySpotXmm * frame.PrimarySpotXmm + frame.PrimarySpotYmm * frame.PrimarySpotYmm);
            double twoTheta = Math.Atan2(rPrimary, frame.DetectorDistanceMm);
            double theta = twoTheta * 0.5;

            // Target alignment is centering spot at origin (0, 0)
            double phiSpot = Math.Atan2(frame.PrimarySpotYmm, frame.PrimarySpotXmm);
            double errRad = theta;

            double dErr = (errRad - _prevErrorRad) / _dt;
            _prevErrorRad = errRad;

            // Goniometer Euler angle commands
            double corrMag = (_kp * errRad) + (_kd * dErr);
            corrMag = Math.Clamp(corrMag, -0.05, 0.05); // Radian clamp

            double dPhiDeg = -corrMag * Math.Cos(phiSpot) * (180.0 / Math.PI);
            double dThetaDeg = -corrMag * Math.Sin(phiSpot) * (180.0 / Math.PI);
            double dPsiDeg = 0.0; // Roll around beam

            double errArcSec = errRad * (180.0 / Math.PI) * 3600.0;

            cmd.RotationPhiDeg = dPhiDeg;
            cmd.RotationThetaDeg = dThetaDeg;
            cmd.RotationPsiDeg = dPsiDeg;
            cmd.MisalignmentErrorArcSec = errArcSec;
            cmd.IsCrystalOriented = Math.Abs(errArcSec) <= 1.0; // Sub-arcsecond alignment
            cmd.IsPatternIndexed = rPrimary > 0.01;
        }
    }
}

4. 교육 및 실무 적용 방안

  • 한국방송통신대학교 신소재공학/결정학: 역격자 공간 Ewald 구면 해석, 라우에 반사 대칭성 및 오일러 각도 변환 가상실습 교구.
  • 포항방사광가속기(PAL) 빔라인 및 웨이퍼 제조사: 고휘도 백색 X선 빔라인 단결정 기판 고속 자동 오리엔테이션 제어기 탑재.