Options
The Options dataclasses are the main user-facing interface for configuring
Pty-Chi when you use the TaskManager API. In a typical workflow, you build one
high-level options object, fill in its fields, and pass it to
ptychi.api.task.PtychographyTask.
Hierarchy of Options Objects
The highest-level options classes used for ptychography tasks are subclasses of
PtychographyTaskOptions. These classes bundle together the configuration of
the full reconstruction job:
data_options: diffraction patterns and experimental metadatareconstructor_options: settings for the reconstruction loop, such as batch size and number of epochsobject_options: settings for the reconstructed objectprobe_options: settings for the reconstructed probeprobe_position_options: settings for scan positions and position correctionopr_mode_weight_options: settings for OPR mode weights
The top-level subclass determines the reconstruction engine and the concrete types of the nested options objects. For example:
import ptychi.api as api
options = api.LSQMLOptions()
# Uses LSQMLReconstructorOptions, LSQMLObjectOptions, LSQMLProbeOptions, ...
options = api.EPIEOptions()
# Uses EPIE / PIE-specific nested options
options = api.AutodiffPtychographyOptions()
# Uses autodiff-specific nested options
In other words, choosing api.LSQMLOptions(), api.PIEOptions(),
api.DMOptions(), or another top-level options class is how you choose the
engine to run.
Constructing an Options Object
The example below shows the typical pattern: instantiate a top-level task options object, then populate its nested options objects.
import torch
import ptychi.api as api
from ptychi.utils import get_default_complex_dtype, get_suggested_object_size
data, probe, pixel_size_m, positions_px = your_data_loading_function()
options = api.LSQMLOptions()
options.data_options.data = data
options.object_options.initial_guess = torch.ones(
[1, *get_suggested_object_size(positions_px, probe.shape[-2:], extra=100)],
dtype=get_default_complex_dtype(),
)
options.object_options.pixel_size_m = pixel_size_m
options.object_options.optimizable = True
options.object_options.optimizer = api.Optimizers.SGD
options.object_options.step_size = 1.0
options.probe_options.initial_guess = probe
options.probe_options.optimizable = True
options.probe_options.optimizer = api.Optimizers.SGD
options.probe_options.step_size = 1.0
options.probe_position_options.position_x_px = positions_px[:, 1]
options.probe_position_options.position_y_px = positions_px[:, 0]
options.probe_position_options.optimizable = False
options.reconstructor_options.batch_size = 64
options.reconstructor_options.num_epochs = 16
After the options object is configured, pass it to PtychographyTask:
from ptychi.api.task import PtychographyTask
task = PtychographyTask(options)
task.run()
ParameterOptions
The object, probe, probe positions, and OPR mode weights are each configured by
a subclass of ParameterOptions. These parameter-level options define:
whether the parameter is optimizable
which optimizer to use
the initial
step_sizeoptimizer keyword arguments in
optimizer_paramswhen the parameter is optimized through
optimization_plan
For example, you can optimize the object from the beginning of the run, but delay probe updates until later:
import ptychi.api as api
options = api.LSQMLOptions()
options.object_options.optimizable = True
options.object_options.optimizer = api.Optimizers.SGD
options.object_options.step_size = 1.0
options.probe_options.optimizable = True
options.probe_options.optimizer = api.Optimizers.SGD
options.probe_options.step_size = 1.0
options.probe_options.optimization_plan.start = 5
OptimizationPlan
Each ParameterOptions object contains an optimization_plan. This plan
controls when the corresponding parameter is updated.
The most commonly used fields are:
start: first epoch where optimization is allowedstop: first epoch where optimization is no longer allowedstride: optimize everystrideepochsstep_size_scheduler_class: optional scheduler class name fromtorch.optim.lr_schedulerstep_size_scheduler_options: keyword arguments for that scheduler, excludingoptimizer
Example:
import ptychi.api as api
options = api.EPIEOptions()
options.probe_options.optimizable = True
options.probe_options.optimizer = api.Optimizers.SGD
options.probe_options.step_size = 0.1
plan = options.probe_options.optimization_plan
plan.start = 10
plan.stop = 100
plan.stride = 2
This means the probe starts updating at epoch 10, stops before epoch 100, and is updated every other epoch.
Step Size Schedulers
Step size schedulers are configured per parameter through
ParameterOptions.optimization_plan. This is useful when the object, probe,
and probe positions need different schedules.
To enable a scheduler, set step_size_scheduler_class to the name of a class
in torch.optim.lr_scheduler and pass the scheduler constructor arguments in
step_size_scheduler_options.
import ptychi.api as api
options = api.LSQMLOptions()
options.object_options.optimizable = True
options.object_options.optimizer = api.Optimizers.SGD
options.object_options.step_size = 1.0
options.object_options.optimization_plan.step_size_scheduler_class = "ExponentialLR"
options.object_options.optimization_plan.step_size_scheduler_options = {
"gamma": 0.98,
}
options.probe_options.optimizable = True
options.probe_options.optimizer = api.Optimizers.Adam
options.probe_options.step_size = 1e-2
options.probe_options.optimization_plan.step_size_scheduler_class = "StepLR"
options.probe_options.optimization_plan.step_size_scheduler_options = {
"step_size": 20,
"gamma": 0.5,
}
If step_size_scheduler_class is left as None, no scheduler is used for
that parameter.
Schedulers are stepped internally at the end of each epoch while the parameter
is inside its optimization interval, so the same scheduler mechanism applies to
parameters updated through optimizer.step() and to parameters whose update
rules use the current step size explicitly.