Reflectometry Plugin Documentation¶
Overview¶
The Reflectometry Plugin extends VIPR for analyzing thin film structures using X-ray (XRR) and neutron reflectometry (NR) data. It determines layer properties such as thickness, roughness, and scattering length density (SLD) through three distinct model approaches: Reflectorch (deep learning), Flow Models (NSF/MAF/CINN normalizing flows), and PANPE (prior-amortized neural posterior estimation).
Application Domain: Inverse problem solving for reflectometry - predicting layer parameters from experimental reflectivity curves.
Plugin Architecture¶
Modular Structure¶
The plugin implements a three-submodule architecture with shared components:
vipr_reflectometry/
├── shared/ # Shared components (data loaders, preprocessing)
├── reflectorch/ # Deep learning models (EasyInferenceModel)
├── flow_models/ # Normalizing flow models (NSF, MAF, CINN)
└── panpe/ # Prior-Amortized Neural Posterior Estimation (optional)
Submodule Loading Pattern¶
Each submodule follows the VIPR plugin loading convention with a load(app) function:
# vipr_reflectometry/__init__.py
def load(app):
"""Load plugin with all submodules."""
# Register environment defaults hook
app.hook.register('INFERENCE_BEFORE_START_HOOK', setup_reflectometry_env_defaults)
# Load shared components first (data loaders used by multiple submodules)
from . import shared
shared.load(app)
# Load submodules
from . import reflectorch
reflectorch.load(app)
from . import flow_models
flow_models.load(app)
# Optional submodule
try:
from . import panpe
panpe.load(app)
except ImportError:
app.log.info("PANPE not installed (optional)")
Key Pattern:
Each submodule (including
shared) has its ownload(app)functionClean separation of concerns - no cross-submodule handler registration
Handler Registration Strategy¶
Submodules register handlers specific to their model approach:
# reflectorch/load(app)
def load(app):
# Register handlers
app.handler.register(ReflectorchModelLoader)
app.handler.register(ReflectorchPredictor)
# Extend app with custom functionality
app.extend('reflectorch', Reflectorch(app))
app.extend('reflectorch_dc', ReflectorchDataCollector(app))
Pattern Used:
Handler registration via
app.handler.register()App extension via
app.extend()for domain-specific utilitiesData collector pattern for UI visualization
Framework Integration Points¶
1. Discovery Decorators¶
Handlers use @discover_* decorators for automatic parameter exposure (see Discovery Plugin for details):
@discover_data_loader('csv_spectrareader', {
'data_path': {'type': 'str', 'required': True},
'column_mapping': {'type': 'dict', 'required': False}
})
class CSVSpectraReaderDataLoader(DataLoaderHandler):
pass
2. DataSet Transfer Object¶
All data loaders return the VIPR DataSet object:
return DataSet(
x=q_values, # (batch_size, n_points)
y=intensities, # (batch_size, n_points)
dx=q_errors, # Optional uncertainties
dy=intensity_errors, # Optional uncertainties
metadata={'loader': 'csv_spectrareader', ...}
)
3. Filter System Integration¶
Preprocessing uses weighted filters in the inference pipeline:
@discover_filter(
'INFERENCE_PREPROCESS_PRE_FILTER',
weight=-10, # Runs before Reflectorch interpolation (weight=0)
parameters={...}
)
def clean_experimental_data(self, data: DataSet, **kwargs) -> DataSet:
# Transform and return DataSet
return cleaned_dataset
4. Hook System¶
Environment setup via hooks before inference starts:
def setup_reflectometry_env_defaults(app):
"""Set environment defaults before inference."""
if 'REFLECTORCH_ROOT_DIR' not in os.environ:
os.environ['REFLECTORCH_ROOT_DIR'] = str(Path.cwd() / 'storage' / 'reflectorch')
# Register in plugin loading
app.hook.register('INFERENCE_BEFORE_START_HOOK', setup_reflectometry_env_defaults)
Registered Components¶
Model Loaders¶
Handler Label |
Submodule |
Purpose |
|---|---|---|
|
reflectorch |
Load Reflectorch deep learning models |
|
flow_models |
Load normalizing flow models |
|
panpe |
Load PANPE models (optional) |
Data Loaders¶
Handler Label |
Format |
Batch Size |
|---|---|---|
|
CSV/DAT/TXT |
1 |
|
HDF5 |
N |
Predictors¶
Handler Label |
Submodule |
Output Type |
|---|---|---|
|
reflectorch |
Layer parameters + SLD profiles |
|
flow_models |
Posterior samples |
|
panpe |
Posterior samples (optional) |
Filters¶
Filter |
Weight |
Purpose |
|---|---|---|
|
-10 |
Remove negative/high-error points |
|
0 |
Interpolate to model grid |
|
0 |
Prepare for flow models |
Environment Configuration¶
Required Variables¶
export REFLECTORCH_ROOT_DIR=${PWD}/storage/reflectorch # Required for model/config storage
The plugin automatically sets this if not defined, using ${PWD}/storage/reflectorch as default.
Directory Structure¶
storage/reflectorch/
├── configs/ # Model configuration files
├── saved_models/ # Trained model weights
└── cache/ # Downloaded models (Reflectorch)
Installation¶
Basic Installation¶
pip install git+https://codebase.helmholtz.cloud/vipr/vipr-core.git
pip install git+https://codebase.helmholtz.cloud/vipr/vipr-reflectometry-plugin.git
With PANPE Support¶
pip install "git+https://codebase.helmholtz.cloud/vipr/vipr-reflectometry-plugin.git[plugin-panpe]"
Local Development¶
cd vipr-reflectometry-plugin
pip install -e .
# With PANPE
pip install -e .[plugin-panpe]
Quick Start¶
CLI Usage¶
# Reflectorch XRR analysis
vipr --config '@vipr_reflectometry/reflectorch/examples/configs/PTCDI-C3.yaml' inference run
# Flow model inference
vipr --config '@vipr_reflectometry/flow_models/examples/configs/NSF_XRR.yaml' inference run
Configuration Pattern¶
vipr:
inference:
load_data:
handler: csv_spectrareader
parameters:
data_path: '@vipr_reflectometry/reflectorch/examples/data/D17_SiO.dat'
load_model:
handler: reflectorch
parameters:
config_name: e_mc_point_neutron_conv_standard_L1_InputQDq_n256_size1024
prediction:
handler: reflectorch_predictor
parameters:
calc_pred_curve: true
calc_pred_sld_profile: true
Documentation¶
Quick Links¶
Handler Implementation - DataLoader, ModelLoader, Predictor patterns
Filters & Hooks - Preprocessing and workflow integration
Examples - Complete workflow configurations