Physics-Ellipsometry-VASE
view release on metacpan or search on metacpan
# Physics::Ellipsometry::VASE
Variable Angle Spectroscopic Ellipsometry analysis for Perl / PDL.
## Description
Physics::Ellipsometry::VASE is a complete framework for spectroscopic
ellipsometry data analysis. It includes built-in optical models, a transfer
matrix method, and global optimisation â so you can go from raw VASE data to
fitted film parameters in a few lines of code.
### Core features
- **Data loading** â simple whitespace-delimited files and native J.A. Woollam
VASE instrument format (auto-detected), with automatic eV â nm conversion
- **Transfer Matrix Method** (`VASE::TMM`) â physics sign convention
(*e*<sup>+2*iβ*</sup>), Verdet Fresnel coefficients, arbitrary layer counts
- **Dispersion models** (`VASE::Dispersion`) â Cauchy, Sellmeier, Tauc-Lorentz,
Drude, General Oscillator
- **EMA mixing rules** (`VASE::EMA`) â Linear, Bruggeman, Maxwell-Garnett
- **Material file loader** (`VASE::Materials`) â point-by-point `.mat` files
with automatic eV/nm unit handling and interpolation
- **Circular Delta residuals** â proper handling of the 0°/360° wrap in the
Levenberg-Marquardt objective function
- **Parameter bounds & vary/fix** (`VASE::Parameter`) â logit-transformed
bounded optimisation, fixed-parameter support
- **Global optimiser** (`VASE::Optimizer`) â Differential Evolution
(DE/rand/1/bin) and grid search for initial parameter estimation
- **Weighted fitting** â uses measured uncertainties (sigma) from Woollam files
- **Numerical Jacobian** â configurable finite-difference step with minimum
absolute floor
- **Plotting** â multi-angle colour-coded overlays via PDL::Graphics::Gnuplot
## Installation
From source:
```bash
perl Makefile.PL
make
make test
make install
```
## Quick Start
```perl
use PDL;
use PDL::NiceSlice;
use Physics::Ellipsometry::VASE;
use Physics::Ellipsometry::VASE::TMM qw(psi_delta);
use Physics::Ellipsometry::VASE::Dispersion qw(cauchy_nk);
use Physics::Ellipsometry::VASE::Materials qw(load_material interpolate_material);
# Load data and substrate material
my $vase = Physics::Ellipsometry::VASE->new(
layers => 2,
circular_delta => 1, # circular Delta residuals
deriv_step => 1e-3,
);
$vase->load_data('measurement.dat');
my $substrate = load_material('si_jaw.mat');
# Model: Air / Cauchy film / Si substrate
sub my_model {
my ($params, $x) = @_;
my $lambda = $x->(:,0);
my $theta = $x->(:,1);
my ($n_film, $k_film) = cauchy_nk($lambda, $params->at(0), $params->at(1), 0);
my $N_film = $n_film + i() * $k_film;
my ($n_sub, $k_sub) = interpolate_material($substrate, $lambda);
my $N_sub = $n_sub + i() * $k_sub;
my $N_air = pdl(1.0) + i() * pdl(0.0);
my $d_nm = $params->at(2);
my ($psi, $delta) = psi_delta(
$lambda, $theta,
[$N_air, $N_film, $N_sub],
[$d_nm],
);
return $psi->append($delta);
}
$vase->set_model(\&my_model);
my $fitted = $vase->fit(pdl [2.0, 0.01, 100.0]);
my $mse = $vase->mse($fitted, nparams => 3);
printf "MSE = %.4f, thickness = %.1f nm\n", $mse, $fitted->at(2);
( run in 0.624 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )