NAME

Physics::Ellipsometry::VASE - Variable Angle Spectroscopic Ellipsometry data fitting

VERSION

Version 0.01

SYNOPSIS

use PDL;
use PDL::NiceSlice;
use Physics::Ellipsometry::VASE;

my $vase = Physics::Ellipsometry::VASE->new(layers => 1);
$vase->load_data('data.dat');

sub my_model {
    my ($params, $x) = @_;
    my $a = $params->(0);
    my $b = $params->(1);
    my $c = $params->(2);
    my $d = $params->(3);
    my $wavelength = $x->(:,0);

    my $psi   = $a - $b * $wavelength;
    my $delta = $c + $d * $wavelength;

    return cat($psi, $delta)->flat;
}

$vase->set_model(\&my_model);

my $fit_params = $vase->fit(pdl [65, 0.05, 80, 0.1]);
print "Fitted: $fit_params\n";

DESCRIPTION

Physics::Ellipsometry::VASE provides Levenberg-Marquardt fitting of user-defined optical models to variable angle spectroscopic ellipsometry (VASE) data. It wraps PDL::Fit::LM and handles the bookkeeping of mapping between the simple user model interface and the lmfit calling convention, including automatic numerical computation of the Jacobian via finite differences.

Ellipsometry measures the change in polarization state of light reflected from a surface. The two measured quantities are Psi (amplitude ratio) and Delta (phase difference). This module fits models that predict both Psi and Delta simultaneously as a function of wavelength and angle of incidence.

DATA FORMAT

Input files should contain whitespace-separated columns:

# Wavelength(nm)  Angle(deg)  Psi(deg)  Delta(deg)
400  70  45.0  120.0
410  70  44.5  121.0

Lines beginning with # and blank lines are skipped.

MODEL FUNCTIONS

A model function receives two arguments and must return a single flattened PDL piddle:

sub model {
    my ($params, $x) = @_;

    # $params: PDL piddle of fit parameters
    # $x:      PDL piddle of shape (npoints, 2)
    #          $x->(:,0) = wavelength (nm)
    #          $x->(:,1) = angle of incidence (deg)

    my $psi   = ...;   # compute Psi  (npoints)
    my $delta = ...;   # compute Delta (npoints)

    return cat($psi, $delta)->flat;
}

The Jacobian (partial derivatives with respect to parameters) is computed automatically via numerical finite differences.

METHODS

new

my $vase = Physics::Ellipsometry::VASE->new(%args);

Constructor. Accepts:

layers

Number of layers in the optical model (default: 1).

model

Optional code reference to a model function.

load_data

$vase->load_data($filename);

Reads ellipsometry data from a whitespace-delimited file. Returns the loaded data as a PDL piddle.

set_model

$vase->set_model(\&model_func);

Sets the model function used for fitting.

fit

my $fitted_params = $vase->fit($initial_params);

Performs Levenberg-Marquardt fitting. $initial_params is a PDL piddle of initial guesses. Returns a PDL piddle of fitted parameters.

DEPENDENCIES

PDL, PDL::Fit::LM, PDL::NiceSlice

AUTHOR

jtrujil1

LICENSE AND COPYRIGHT

This software is copyright (c) 2026.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.