Handler Implementation Patterns

See also

Related Documentation:

This document details how the Reflectometry Plugin implements VIPR handler interfaces for data loading, model loading, and prediction.

DataLoader Handlers

CSV/DAT/TXT DataLoader

Handler: vipr-reflectometry:vipr_reflectometry.shared.load_data.csv_spectrareader_data_loader.CSVSpectraReaderDataLoader
Label: csv_spectrareader
Interface: vipr.interfaces.data_loader.DataLoaderInterface

Key Patterns:

HDF5 DataLoader

Handler: vipr-reflectometry:vipr_reflectometry.shared.load_data.hdf5_spectrareader_data_loader.HDF5SpectraReaderDataLoader
Label: hdf5_spectrareader
Batch Loading: Loads multiple spectra (batch_size > 1)

Key Patterns:

ModelLoader Handlers

Reflectorch ModelLoader

Handler: vipr-reflectometry:vipr_reflectometry.reflectorch.load_model.reflectorch_model_loader.ReflectorchModelLoader
Label: reflectorch
External Library: reflectorch (EasyInferenceModel)

Key Patterns:

  • Inherits from vipr.handlers.model_loader.ModelLoaderHandler

  • Method signature: _load_model(**kwargs) -> Any

  • Environment variable integration for paths (REFLECTOMETRY_ROOT_DIR)

  • Returns library-specific model object (no wrapping required)

  • Uses local model/config files from REFLECTOMETRY_ROOT_DIR/reflectorch (typically prepared via the Hugging Face plugin)

Flow Model Loader

Handler: vipr-reflectometry:vipr_reflectometry.flow_models.load_model.flow_model_loader.FlowModelLoader
Label: flow_model_loader
External Library: PyTorch + custom NSF-based flow architectures

Key Patterns:

  • Inherits from vipr.handlers.model_loader.ModelLoaderHandler

  • Access inference workflow attributes: self.app.inference.device

  • Configuration loading from external libraries

  • Checkpoint loading and state dict management

  • Model preparation (device placement, eval mode)

Predictor Handlers

Reflectorch Predictor

Handler: vipr-reflectometry:vipr_reflectometry.reflectorch.predict.reflectorch_predictor.ReflectorchPredictor
Label: reflectorch_predictor
Input: DataSet + Model
Output: Dictionary with predictions

Key Patterns:

  • Inherits from vipr.handlers.predictor.PredictorHandler

  • Access workflow state: self.app.inference.preprocessed_data, self.app.inference.model

  • Method signature: _predict(dataset, model, params) -> dict[str, Any]

  • Configurable post-processing via parameters

  • Returns structured dictionary (not DataSet)

Flow Predictor

Handler: vipr-reflectometry:vipr_reflectometry.flow_models.predict.flow_predictor.FlowPredictor
Label: flow_predictor
Output: Posterior samples

Key Patterns:

Handler Registration

Handlers are registered in submodule load(app) functions:

# shared/__init__.py
def load(app):
    """Load shared handlers used by multiple submodules."""
    # Register shared data loaders
    app.handler.register(HDF5SpectraReaderDataLoader)
    app.handler.register(CSVSpectraReaderDataLoader)
    
    # Register shared controller
    app.handler.register(ReflectometryController)

# reflectorch/__init__.py
def load(app):
    """Load reflectorch-specific handlers."""
    # Register only reflectorch handlers
    app.handler.register(ReflectorchModelLoader)
    app.handler.register(ReflectorchPredictor)

# flow_models/__init__.py
def load(app):
    """Load flow-specific handlers."""
    # Register only flow handlers
    app.handler.register(FlowModelLoader)
    app.handler.register(FlowPredictor)

Pattern:

  • Shared handlers registered in shared/__init__.py (single source of truth)

  • Each submodule registers only its own handlers

  • Main plugin loads shared first, then submodules

Configuration Usage

Handlers are selected in YAML configuration:

vipr:
  inference:
    load_data:
      handler: csv_spectrareader  # Handler label
      parameters:
        data_path: '@vipr_reflectometry/examples/data/D17_SiO.dat'
        column_mapping:
          q: 0
          I: 1
          dI: 2
    
    load_model:
      handler: reflectorch  # Handler label
      parameters:
        config_name: e_mc_point_neutron_conv_standard_L1_InputQDq_n256_size1024
    
    prediction:
      handler: reflectorch_predictor  # Handler label
      parameters:
        calc_pred_curve: true
        calc_pred_sld_profile: true

Key Takeaways

Handler Implementation Checklist

  1. ✅ Inherit from appropriate base class (DataLoaderHandler, ModelLoaderHandler, PredictorHandler)

  2. ✅ Use @discover_* decorator with parameter schema

  3. ✅ Implement required method (_load_data, _load_model, _predict)

  4. ✅ Return appropriate type (DataSet, model object, dict)

  5. ✅ Register handler in submodule load(app) function

VIPR Framework Patterns Used

  • Discovery System: Parameter exposure via decorators

  • Handler Registry: Dynamic handler lookup by label

  • Transfer Object: Immutable DataSet for data flow

  • Workflow Integration: Access workflow state via self.app.inference.*

  • Configuration-Driven: YAML configuration selects handlers and parameters