ptyrad.params.init_params

Contents

ptyrad.params.init_params#

Defines available options and validation rules for the init_params dictionary.

Note that init_params contains dataset-dependent required fields.

pydantic model ptyrad.params.init_params.InitParams[source]#

Bases: BaseModel

The init_params can be roughly categorized into 4 parts:

  1. Experimental params (kv, convergence angle, aberrations)

  2. Model complexity (number of probe / object modes, number of object slices and slice thickness)

  3. Preprocessing (permutation, reshaping, flipping, cropping, padding, and normalization)

  4. Input source and params (where and how to load / initialize the diffraction pattern, probe, object)

Most of the fields in init_params are dataset-dependent, so users must manually check and input values. While the preprocessing steps are not required fields, incorrect data orientation (meas_flipT) would lead to incorrect reconstructions, so it’s practically required.

Fields:
param random_seed: int | None = None#

Random seed is used to initialize the random number generator for improved reproducibility.

Example:

'random_seed': 42

Or direcly passed in from CLI with:

ptyrad run --params_path <PATH> --seed 42

Note

This random seed is used for both initialization and reconstruction. For multiGPU, a fixed seed is automatically generated if not provided to ensure both GPUs started from the exact same object, probe, and positions.

param probe_illum_type: Literal['electron', 'xray'] = 'electron'#

Type of probe illumination, choose between electron or xray.

Example:

'probe_illum_type': 'electron'

This affects the required fields for probe generation, as electron and x-ray ptychography use different parameters.

param probe_kv: float | None = None#

[kV] Acceleration voltage for relativistic electron wavelength calculation

Example:

'probe_conv_angle': 24.9

Required for 'probe_illum_type': 'electron'

param probe_conv_angle: float | None = None#

[mrad] Semi-convergence angle in mrad for probe-forming aperture

Example:

'probe_conv_angle': 24.9

Required for 'probe_illum_type': 'electron'

Warning

This value should be experimentally calibrated as close as possible, as it could affect the real and k-space px size calibration if useing 'meas_calibration': {'mode': 'fitRBF'}.

param probe_aberrations: Dict[str, Any] [Optional]#

[Ang, degree] Aberration coefficients for electron probe.

Example:

'probe_aberrations': {'C10': 200, 'A1': 50, 'A1phi': 25, 'C21a': 300, 'C23': 400, 'phi23': 25, 'Cs': 5000}

Supports Krivanek (polar and cartesian), Haider notations, common aliases, or a mix of them.

Aberrations will be internally normalized to Krivanek polar while generating the probe.

  • Krivanek polar: C10, C21, phi21, etc.

    \(C_{nm} = \sqrt{C_{nma}^2 + C_{nmb}^2}\)

    \(\phi_{nm} = \arctan(\frac{C_{nmb}}{C_{nma}}) / m\)

  • Krivanek cartesian: C21a, C21b, etc.

    \(C_{nma} = C_{nm} * cos(m * \phi_{nm})\)

    \(C_{nmb} = C_{nm} * sin(m * \phi_{nm})\)

    \(C_{nm, complex} = C_{nma} + iC_{nmb}\)

  • Haider notation: A1, A1phi, B2, B2phi, etc. Only supported up to A5 (equivalently C56).

  • Common aliases: defocus, Cs are also supported.

Note

C10 = -df, and positive C10 refers to overfocus (stronger lens) following Kirkland/abtem convention. See https://ptyrad.readthedocs.io/en/latest/_autosummary/ptyrad.utils.aberrations.html#module-ptyrad.utils.aberrations for more details.

param beam_kev: float | None = None#

[keV] X-ray beam energy for photon wavelength calculation

Required for 'probe_illum_type': 'xray'

param probe_dRn: float | None = None#

[meter] Width of the outermost zone for X-ray probes using Fresnel zone plates (FZP)

Required for 'probe_illum_type': 'xray'

param probe_Rn: float | None = None#

[meter] Radius of the outermost zone for X-ray probes using Fresnel zone plates (FZP)

Required for 'probe_illum_type': 'xray'

param probe_D_H: float | None = None#

[meter] Diameter of the central beamstop for X-ray probes using Fresnel zone plates (FZP)

Required for 'probe_illum_type': 'xray'

param probe_D_FZP: float | None = None#

[meter] Diameter of pinhole for X-ray probes using Fresnel zone plates (FZP)

Required for 'probe_illum_type': 'xray'

param probe_Ls: float | None = None#

[meter] Distance from the focal plane to the sample for X-ray probes using Fresnel zone plates (FZP)

Required for 'probe_illum_type': 'xray'

param meas_Npix: int [Required]#

Detector pixel number, EMPAD is 128.

Only supports square detector (ky = kx) for simplicity.

Example:

'meas_Npix': 128

Note

This value always refer to the raw data pixel number, and is used to load and validate the raw data while loading. If a user loaded a dataset with Npix=128, and later upsample it with meas_resample by a factor of 2, PtyRAD will automatically update meas_Npix internally to 256. Same logic for other dimension-modifying preprocessing.

param pos_N_scans: int [Required]#

Number of probe positions (or equivalently diffraction patterns since 1 DP / position)

Example:

'pos_N_scans': 16384

Note

pos_N_scans is optional for raster scan, since it can be internally inferred from pos_N_scan_slow * pos_N_scan_fast. However, pos_N_scans is required when using custom positions ('pos_source': 'custom') like spiral or other scan patterns. In those cases, pos_N_scans is required, while pos_N_scan_slow and pos_N_scan_fast would need to satisfy pos_N_scan_slow * pos_N_scan_fast = pos_N_scans in order to pass the consistency test by the end of initialization.

param pos_N_scan_slow: int [Required]#

Number of scan position along slow scan direction. Usually it’s the vertical direction of acquisition GUI

Example:

'pos_N_scan_slow': 128

Note

This value always refer to the raw data scan dimension, and is used to load and validate the raw data while loading. If a user loaded a dataset with N_scan_slow = 128, and later crop it with meas_crop to 64, PtyRAD will automatically update pos_N_scan_slow internally to 64. Same logic for other dimension-modifying preprocessing.

Note

For custom scan positions ('pos_source': 'custom') that doesn’t have so-called fast/slow scan directions, put in values such that pos_N_scan_slow * pos_N_scan_fast = pos_N_scans to pass the consistency test by the end of initialization.

param pos_N_scan_fast: int [Required]#

Number of scan position along fast scan direction. Usually it’s the horizontal direction of acquisition GUI

Example:

'pos_N_scan_fast': 128

Note

This value always refer to the raw data scan dimension, and is used to load and validate the raw data while loading. If a user loaded a dataset with N_scan_fast = 128, and later crop it with meas_crop to 64, PtyRAD will automatically update pos_N_scan_fast internally to 64. Same logic for other dimension-modifying preprocessing.

Note

For custom scan positions ('pos_source': 'custom') that doesn’t have so-called fast/slow scan directions, put in values such that pos_N_scan_slow * pos_N_scan_fast = pos_N_scans to pass the consistency test by the end of initialization.

param pos_scan_step_size: float [Required]#

[Ang] Step size between probe positions in a rectangular raster scan pattern.

Example:

'pos_scan_step_size': 0.415

Warning

This value should be experimentally calibrated as close as possible. Incorrect scan step size is equivalent to a global scaling of the scan pattern. Even a 2-5% error can take more than 30K iterations to properly converge, and larger error can cause significant gridding artifacts.

If possible, always acquire data when the stage is stable, or pre-calibrate a dataset-dependent scan step size to accelerate convergence of ptychographic reconstructions. See tutorial notebook: chiahao3/ptyrad

param meas_calibration: MeasCalibration [Optional]#

Calibration mode for the measurements (i.e., diffraction patterns) pixel size.

Example:

'meas_calibration': {'mode': 'fitRBF'}

See MeasCalibration for more details.

Warning

Ptychography is very sensitive to microscope calibration, and mis-calibration can lead to slow, incorrect, or even failed reconstructions. Factory or institutional calibration can often be 5-10% off (convergence angle, scan step size) and the accuracy is also often kV-dependent. Users are strongly advised to perform proper microscope calibration to ensure accurate results.

param probe_pmode_max: int = 4#

Maximum number of mixed probe modes.

Example:

'probe_pmode_max': 4

Set to probe_pmode_max = 1 for single probe state, probe_pmode_max > 1 for mixed-state probe during initialization.

Typical values of suggested probe modes are 4 to 12, depends on the coherence of the probe.

For simulated initial probe, it’ll be generated with the specified number of probe modes.

For loaded probe, the pmode dimension would be capped or padded to this number.

Note

The required reconstruction time often scale linearly with number of probe modes, along with a non-zero intercept.

param probe_pmode_init_pows: List[float] = [0.02]#

List of 1 or a few (up to pmode_max) floats.

This specifies initial power(s) for each additional probe modes.

Example:

'probe_pmode_init_pows': [0.02]

If set at [0.02], all additional probe modes would contain 2% of the total intensity.

sum(pmode_init_pows) must be 1 if len(pmode_init_pows) > 1.

See ptyrad.optics.probe.make_mixed_probe for more details

param obj_omode_max: int = 1#

Maximum number of mixed object modes.

Example:

'obj_omode_max': 1

Set to obj_omode_max = 1 for single object state, obj_omode_max > 1 for mixed-state object during initialization.

For simulated initial object, it’ll be generated with the specified number of object modes.

For loaded object, the omode dimension would be capped or padded to at this number.

Note

The required reconstruction time often scale linearly with number of object modes, along with a non-zero intercept.

param obj_omode_init_occu: ObjOmodeInitOccu [Optional]#

Occupancy type and value for mixed-object modes.

Typically we do ‘uniform’ for frozen phonon like configurations.

Example:

'obj_omode_init_occu': {'occu_type': 'uniform', 'init_occu': null}

See ObjOmodeInitOccu for more details.

param obj_Nlayer: int [Required]#

Number of slices for multislice object.

Example:

'obj_Nlayer': 1

Set to obj_Nlayer = 1 for single slice object, obj_Nlayer > 1 for multislice object during initialization.

For quick params check, single slice ptychography can often give fair results for 10-15 nm thick specimens with light/medium atoms.

However, most electron microscopy specimens (except monolayer graphene) exhibit noticeable multiple scatterings,

so multislice ptychography is often helpful / required for improved reconstruction quality and quantitativeness.

Note

The required reconstruction time often scale linearly with number of layers, along with a non-zero intercept. Reconstruction with more than 40 slices can be computationally expensive and less stable.

param obj_slice_thickness: float [Required]#

[Ang] Slice thickness (propagation distance) for multislice ptychography.

Example:

'obj_slice_thickness': 10

Typical values are between 1 to 20 Ang, for most samples 10 Ang (1 nm) is a good starting point.

Slice thickness has no effect for single-slice ptychography.

Note

Comparing to conventional multislice formalism (slice thickness ~ 1 Ang), multislice electron ptychography (MEP) is making a wild approximation to trade for speed. Although using 1-nm-thick slices seems to give qualitativly correct result with MEP, it will not match with high-precision quantitative electron diffraction simulation with 1-Ang-slice.

param simu_Npix: int | None = None#

Simulated diffraction pattern pixel number. Can be equal or larger than meas_Npix.

Only supports square detector (ky = kx) for simplicity.

Example:

'simu_Npix': 128
param simu_match_mode: Literal['crop', 'resample'] | None = None#

Matching mode for exp and simu diffraction patterns.

This will crop or resample the simulated diffraction pattern so that it matches the dimension of experimental patterns.

Example:

'simu_match_mode': 'crop''
param meas_permute: List[int] | None = None#

Applies additional permutation (reorder axes) to the loaded diffraction patterns with a list of ints.

The syntax is the same as np.transpose().

Example:

'meas_permute': [2, 3, 0, 1]

Note

This is offen needed if the original dataset is arranged as (ky, kx, Ry, Rx), where Ry and Rx are real-space scan dimensions. For such cases, use 'meas_permute': [2, 3, 0, 1] to convert the dataset into (Ry, Rx, ky, kx) first, and then use meas_reshape to make it into (N_scans, ky, kx).

param meas_reshape: List[int] | None = None#

Applies additional reshaping (rearrange elements) to the loaded diffraction patterns with a list of 3 ints.

The syntax is the same as np.reshape().

Example:

'meas_reshape': [-1, 128, 128]

Note

This is often needed to convert the 4D diffraction dataset (Ry,Rx,ky,kx) into 3D (N_scans,ky,kx). We can put 'meas_reshape': [-1, <Npix>, <Npix>] for convenient representation, make sure to replace <Npix> with your actual value in params files.

param meas_flipT: List[int] | None = None#

Applies additional flipping and transposing to the loaded diffraction patterns with a list of 3 binary booleans (0 or 1)

The operation syntax is [flipud, fliplr, transpose], which is the same as PtychoShleves / fold_slice.

Example:

'meas_flipT': [1,0,0]

[1,0,0] means to flip diffraction patterns vertically.

Note

Although the programmic default is null or equivalently [0,0,0], practically we often need to find the correct dataset orientation for each microscope.

Note

Despite pos_scan_flipT can also be used to compensate relative orientation between scan coordinates and diffraction patterns, it’s strongly suggested to use meas_flipT to correct for the dataset orientation, and keep pos_scan_flipT as null. Because pos_scan_flipT would alter the visual layout of “fast/slow” directions, and can cause discrepancy with other simultaneously acquired datasets (like ADF-STEM). Therefore, meas_flipT is the recommended approach, and is the only orientaiton-related value that can be optionally attached to output reconstruction folder name.

param meas_crop: List[List[int] | None] | None = None#

Applies additional cropping to the 4D dataset in both real and k-space with a (4,2) nested list of ints as:

[[scan_slow_start, scan_slow_end], [scan_fast_start, scan_fast_end], [ky_start, ky_end], [kx_start, kx_end]].

Example:

'meas_crop': [[0, 64], [0, 64], null, null]

[[0,64], [0,64], null, null] means cropping scan positions to 64 x 64 in real space, but leaves the k-space untouched.

This is useful for reconstrucing only a subset of real-space probe positions, or to crop the kMax of diffraction patterns.

The slicing syntax follows conventional numpy indexing so the upper bound is not included.

Note

This does NOT affect the file on disk, and is only operating on the loaded array. This feature allows flexible change of reconstruction FOV (if cropping in real space) without processing and saving multiple versions of the same dataset. If cropping in k-space, it will modify kMax and hence the real space pixel size, which can be useful if one want a faster reconstruction (due to smaller Npix). There is no need to modify meas_Npix, pos_N_scans, pos_N_fast_scan, or pos_N_slow_scan with this feature, as the value will be automatically updated internally.

param meas_pad: MeasPad | None = None#

Applies additional padding to the diffraction pattern to side length = 'target_Npix' based on the padding_type.

Example:

'meas_pad': {'mode': 'on_the_fly', 'padding_type': 'power', 'target_Npix': 256, 'value': null, 'threshold': 70}

There are 5 configurational fields, see MeasPad for more details.

Note

Padding the diffraction pattern will increase kMax, and hence reducing the real space pixel size (dx). While the nominal kMax increases, it doesn’t necessarily enhance the ultimate spatial resolution as there’s no actual information about the specimen being added.

param meas_resample: MeasResample | None = None#

Applies additional resampling to the diffraction patterns by 'scale_factors' along ky and kx directions.

Example:

'meas_resample': {'mode': 'on_the_fly', 'scale_factors': [2,2]}

See MeasResample for more details.

Note

Resampling the diffraction pattern does NOT change kMax (or dx), but it will modify the FOV of the probe array. Common usage of resampling is to upsample the diffraction pattern, so that the probe array can have more extended FOV to accomodate the probe. For very large probe size, or thick samples with large convergence angle, this is often needed to reduce edge artifacts of the probe.

param meas_add_source_size: float | None = None#

[Ang] Adds additional spatial partial coherence to diffraction patterns by applying Gaussian blur along scan directions.

Example:

'meas_add_source_size': 0.34

The provided value is used as the std (sigma) of the Gaussian blurring kernel in real space (i.e., it’s mixing nearby diffraction patterns).

This is useful for making simulated datasets more realisitc in a flexible manner, without creating unnecessary copies.

Note

Since FWHM ~ 2.355 std, so a std of 0.34 Ang is equivalent to a source size (FWHM) of 0.8 Ang

param meas_add_detector_blur: float | None = None#

[k-space px] Adds additional detector blur to diffraction patterns to emulate the PSF on detector.

The provided value is used as the std (sigma) for the Gaussian blurring kernel in k-space.

Example:

'meas_add_detector_blur': 1

This is useful for making simulated datasets more realisitc in a flexible manner, without creating unnecessary copies.

Note

This is applied to the “measured”, or “reference” diffraction pattern, so is different from model_params['detector_blur_std'] that applies blurring to the forward simulated diffraction pattern.

param meas_remove_neg_values: MeasRemoveNegValues [Optional]#

Removes negative values or in the measurements (i.e, diffraction patterns).

The measurements array must contain only positive values, so this correction is enforced with a default value of clip_neg.

This can also be used to clip low intensity noises, or to offset the entire baseline by specified values.

Example:

'meas_remove_neg_values': {'mode': 'clip_neg'}

See MeasRemoveNegValues for more details.

Note

For low dose data set with many 0-electron events, it is recommended to use clip_value to clip the 0-electron peak so the background is truly 0. For example, if the 0-electron peak is around 20 counts, then use 'meas_remove_neg_values': {'mode': 'clip_value', 'value': 20} to clip those values, otherwise the probe will absorb the background intensity, which may degrade or even fail the reconstruction.

param meas_normalization: MeasNormalization [Optional]#

Normalization methods of the measurements array.

Example:

'meas_normalization': {'mode': 'max_at_one'}

See MeasNormalization for more details.

Note

Many optimizers are scale dependent and generally works better for values around 1. This normalization keeps the diffraction pattern in a comfortable range for the AD optimizers, and ensures the edge intensities are low enough so that we don’t suffer from significant wrap-around FFT artifacts.

param meas_add_poisson_noise: MeasAddPoissonNoise | None = None#

Applies additional Poisson noise to diffraction patterns to emulate electron dose Poisson statistics.

Example:

'meas_add_poisson_noise': {'unit': 'e_per_Ang2', 'value': 10000}

This is useful for making simulated datasets more realisitc in a flexible manner, without creating unnecessary copies.

See MeasAddPoissonNoise for details.

Note

You can use this to simulate ptychographic reconstruction with different dose conditions using a single noise-free dataset.

param meas_export: bool | MeasExport | None = None#

Exports the final initialized measurements array to disk for further processing, analysis, or visualization.

Example:

'meas_export': {'file_name': 'ptyrad_init_meas', 'file_format': 'hdf5', 'append_shape': True}
'meas_export': true # or null to simply disable

The exported data layout has the same Python convention with py4DGUI so there’s no need to worry about orientation mismatch.

By default the output layout is (N_scans, Ky, Kx), and dropping it to py4DGUI then reshape it into (Ny, Nx, Ky, Kx) keeps the correct orientation.

See MeasExport for details.

Note

This can be used to interactively check whether the meas_flipT is correct.

param probe_permute: List[int] | None = None#

Applies additional permutation (reorder axes) to the loaded probe array with a list of ints.

The syntax is the same as np.transpose().

Example:

'probe_permute': [1, 2, 0]

Note

This can be used to permute custom probe array. For common probe_source` like PtyShv, the permutation is done internally during initialization so this probe_permute is not needed.

param probe_z_shift: float | None = None#

[Ang] Axially shifts the loaded probe along the depth (z) dimension.

Example:

'probe_z_shift': -50.0

The sign convention follows the propagation direction (PtyRAD progrates from top to bottom):

  • Positive (+): Propagates the probe forward (further into the object).

  • Negative (-): Rewinds the probe backward.

Note

This is typically used to conserve the relative geometry between the probe and object when the object is re-centered (e.g., via obj_z_pad, obj_z_crop).

For example, if you pad the object with a 50 Ang vacuum layer ON TOP via obj_z_pad, you should apply a -50 shift to the reconstructed probe to maintain relative geometry of probe and object.

param probe_normalization: ProbeNormalization [Optional]#

Normalization methods for probe intensity.

Example:

'probe_normalization': {'mode': 'mean_total_ints'}

See ProbeNormalization for more details.

Note

Ideally, the probe intensity should match the measurement intensity to ensure the reconstructed object amplitude stays close to 1.

However, for thicker sample with shorter collection angles,

significant amount of electrons are scattered outside of the detector so probe_int > DP_int.

For such cases, use

'probe_normalization': {'mode': 'max_total_ints'}

to normalize the probe intensity by the strongest diffraction pattern (ideally vacuum region) for more accurate reconstruction.

param pos_scan_flipT: List[int] | None = None#

Applies additional flipping and transposing to the scan pattern with a list of 3 binary booleans (0 or 1)

The operation syntax is [flipud, fliplr, transpose], which is the same as PtychoShleves / fold_slice.

Example:

'pos_scan_flipT': [1,0,0]

[1,0,0] means to flip the scan pattern vertically.

Note

Modifying pos_scan_flipT would change the image orientation, so it’s recommended to set this to null, and only use meas_flipT to get the orientation correct.

param pos_scan_affine: List[float] | None = None#

Applies an additional affine transformation to the initialized scan patterns to correct for sample drift or imperfect scan coils.

Example:

'pos_scan_affine': [1.0, 0.0, 2.0, 0.5]

The list must contain 4 floats in the order: [scale, asymmetry, rotation, shear].

  • scale: Global scaling factor

  • asymmetry: Aspect ratio distortion

  • rotation: [deg] Rotation angle

  • shear: [deg] Shear angle

See tutorial notebook: chiahao3/ptyrad

Note

Default is None (equivalent to [1, 0, 0, 0]). This format matches the convention used in PtychoShelves.

param pos_scan_rand_std: float | None = 0.15#

[real space px] Standard deviation of Gaussian distributed random displacements applied to the initial scan positions.

Example:

'pos_scan_rand_std': 0.15

Randomizing the initial guess helps reduce raster grid pathology during reconstruction.

param obj_z_crop: List[int] | None = None#

Applies additional cropping to the 4D object (omode, Nz, Ny, Nx) along the depth dimension to remove unselected layers (e.g., vacuum padding).

Example:

# Keep layers from index 5 to 25
'obj_z_crop': [5, 25]

Takes a list of 2 integers: [z_start, z_end].

Note

The syntax follows conventional numpy indexing, so the upper bound (z_end) is not included. This can be combined with obj_z_pad, obj_z_resample for flexible multislice object initialization.

param obj_z_pad: ObjZPad | None = None#

Applies additional padding to the 4D object (omode, Nz, Ny, Nx) along the depth dimension (Nz).

Example:

'obj_z_pad': {'pad_layers': [2, 2], 'pad_types': ['vacuum', 'vacuum']}

This will pad 2 vacuum layers on top, and another 2 vacuum layer on the bottom.

The obj_Nlayer will be updated automatically.

This is useful for expanding reconstructed object to test object positioning or total thickness.

See ObjZPad for more details.

Note

Padding the top surface effectively changes the entrance plane. You must adjust the axial probe position to maintain the relative geometry:

  • Simulated Probe: Add a corresponding underfocus to probe_aberrations.

  • Loaded Probe: Apply a negative z-shift to probe_z_shift (e.g., if padding 20 Ang (i.e., 2 nm) vacuum on top, use probe_z_shift: -20).

param obj_z_resample: ObjZResample | None = None#

Applies additional resampling to the 4D object along the depth dimension, modifying slice thickness while preserving prod(amp), sum(phase), and total thickness.

Example:

'obj_z_resample': {'mode': 'scale_Nlayer', 'value': 2}

This will double the number of obj_Nlayer while halving the obj_slice_thickness.

See ObjZResample for details.

This is useful for reslicing the reconstructed object into different slice thicknesses, including converting between single-slice and multislice objects.

param meas_source: Literal['file', 'tif', 'tiff', 'mat', 'h5', 'hdf5', 'zarr', 'npy', 'raw', 'custom'] = 'file'#

Data source for the diffraction patterns.

Available options: file, custom. File-type source names like zarr, hdf5, npy, tif, and raw are also accepted for backward compatibility.

param meas_params: FilePathWithKey | np.ndarray [Required]#

Configuration for loading measurement data.

Examples by Source Type:

  • HDF5 / MAT:

    'meas_source': 'file'
    'meas_params': {'path': '/data/scan.h5', 'key': '/entry/data', 'selection': [[0, 64], [0, 64], null, null]}
    
  • Zarr:

    'meas_source': 'file'
    'meas_params': {'path': '/data/scan.zarr', 'key': '/entry/data', 'selection': [[0, 64], [0, 64], null, null]}
    
  • TIF:

    'meas_source': 'file'
    'meas_params': {'path': '/data/scan.tif'}
    
  • EMPAD / Raw (With shape/offset/gap):

    'meas_source': 'file'
    'meas_params': {'path': '/data/scan.raw', 'offset': 0, 'gap': 1024}
    
    # The ``shape`` can be explictly passed in as a list of ints [N, height, width],
    # or it will be automatically filled in from ``init_params``,
    # while ``'offset': 0``, and ``'gap': 1024`` are default values for EMPAD1 datasets.
    
  • Custom (In-memory Numpy):

    # Python code block
    
    # Load the YAML params file as a dict
    params = load_params(params_path, validate=True)
    
    # Update corresponding fields
    params['init_params']['meas_source'] = 'custom'
    params['init_params']['meas_params] = custom_dataset # numpy.array
    
    # Pass params to PtyRADSolver
    ptycho_solver = PtyRADSolver(params, device=device, logger=logger)
    ptycho_solver.run()
    
param probe_source: Literal['simu', 'PtyRAD', 'PtyShv', 'py4DSTEM', 'custom'] = 'simu'#

Data source for the probe.

Available options: simu, PtyRAD, PtyShv, py4DSTEM, custom.

param probe_params: pathlib.Path | np.ndarray | None = None#

Configuration for loading or initializing the probe.

Examples by Source Type:

  • Simulation (Default):

    'probe_source': 'simu'
    'probe_params': null
    
    # Probe will be simulated based on values set in ``init_params``
    # (e.g., kV, conv_angle, aberrations).
    
  • Load from Reconstruction (PtyRAD / PtyShv / py4DSTEM):

    'probe_source': 'PtyRAD'
    'probe_params': '/path/to/previous_reconstruction.h5'
    
  • Custom (In-memory Numpy):

    # Python code block
    
    # Load the YAML params file as a dict
    params = load_params(params_path, validate=True)
    
    # Update corresponding fields
    params['init_params']['probe_source'] = 'custom'
    params['init_params']['probe_params'] = custom_probe_3d # numpy.array
    
    # Pass params to PtyRADSolver
    ptycho_solver = PtyRADSolver(params, device=device, logger=logger)
    ptycho_solver.run()
    
param pos_source: Literal['simu', 'PtyRAD', 'PtyShv', 'py4DSTEM', 'foldslice_hdf5', 'custom'] = 'simu'#

Data source for scan positions.

Available options: simu, PtyRAD, PtyShv, py4DSTEM, foldslice_hdf5, custom.

param pos_params: pathlib.Path | np.ndarray | None = None#

Configuration for loading or initializing scan positions.

Examples by Source Type:

  • Simulation (Default):

    'pos_source': 'simu'
    'pos_params': null
    
    # Positions will be simulated based on ``N_scan_slow``,
    # ``N_scan_fast``, ``scan_step_size``, and ``scan_affine``.
    
  • Load from Reconstruction (PtyRAD / PtyShv / py4DSTE<):

    'pos_source': 'PtyRAD'
    'pos_params': '/path/to/previous_reconstruction.h5'
    
  • APS Instrument Data (fold_slice HDF5):

    'pos_source': 'foldslice_hdf5'
    'pos_params': '/path/to/positions.h5'
    
    # These HDF5 files are generated from APS instruments
    # (previously handled in `fold_slice` via 'p.src_positions=hdf5_pos').
    
  • Custom (In-memory Numpy):

    # Python code block
    
    # Load the YAML params file as a dict
    params = load_params(params_path, validate=True)
    
    # Update corresponding fields
    params['init_params']['pos_source'] = 'custom'
    params['init_params']['pos_params'] = custom_positions_N_by_2 # numpy.array
    
    # Pass params to PtyRADSolver
    ptycho_solver = PtyRADSolver(params, device=device, logger=logger)
    ptycho_solver.run()
    
param obj_source: Literal['simu', 'PtyRAD', 'PtyShv', 'py4DSTEM', 'custom'] = 'simu'#

Data source for the object.

Available options: simu, PtyRAD, PtyShv, py4DSTEM, custom.

param obj_params: List[int] | pathlib.Path | np.ndarray | None = None#

Configuration for loading or initializing the object.

Examples by Source Type:

  • Simulation (Default):

    'obj_source': 'simu'
    'obj_params': [1, 100, 256, 256]
    
    # Format is [omode, Nz, Ny, Nx].
    # Set to null to let PtyRAD automatically determine shape from scan/probe
    # (consistent with PtychoShelves behavior).
    
  • Load from Reconstruction (PtyRAD / PtyShv / py4DSTEM):

    'obj_source': 'PtyRAD'
    'obj_params': '/path/to/previous_reconstruction.h5'
    
  • Custom (In-memory Numpy):

    # Python code block
    
    # Load the YAML params file as a dict
    params = load_params(params_path, validate=True)
    
    # Update corresponding fields
    params['init_params']['obj_source'] = 'custom'
    params['init_params']['obj_params'] = custom_object_4d # numpy.array
    
    # Pass params to PtyRADSolver
    ptycho_solver = PtyRADSolver(params, device=device, logger=logger)
    ptycho_solver.run()
    
param tilt_source: Literal['simu', 'PtyRAD', 'file', 'custom'] = 'simu'#

Data source for object tilts.

Available options: simu, PtyRAD, file, custom.

param tilt_params: TiltParams | FilePathWithKey | pathlib.Path | np.ndarray [Optional]#

Configuration for loading or initializing object tilts.

Examples by Source Type:

  • Simulation (Default):

    'tilt_source': 'simu'
    'tilt_params': {'tilt_type': 'all', 'init_tilts': [[0.0, 0.0]]}
    
    # 'tilt_y' and 'tilt_x' are in mrad.
    # 'tilt_type': 'all' creates a global (1,2) tilt array.
    # 'tilt_type': 'each' creates a position-dependent (N_scans,2) array.
    
  • Load from Reconstruction (PtyRAD):

    'tilt_source': 'PtyRAD'
    'tilt_params': '/path/to/previous_reconstruction.h5'
    
  • Load from File:

    'tilt_source': 'file'
    'tilt_params': {'path': '/data/tilts.mat', 'key': 'tilt_angles'}
    
    # Supported formats: 'tif', 'mat', 'hdf5', 'npy'.
    # Must be 2D array with shape (1,2) or (N,2).
    
  • Custom (In-memory Numpy):

    # Python code block
    
    # Load the YAML params file as a dict
    params = load_params(params_path, validate=True)
    
    # Update corresponding fields
    params['init_params']['tilt_source'] = 'custom'
    params['init_params']['tilt_params'] = custom_tilts # numpy.array (N,2) or (1,2)
    
    # Pass params to PtyRADSolver
    ptycho_solver = PtyRADSolver(params, device=device, logger=logger)
    ptycho_solver.run()
    

Note

Object tilt is implemented via a tilted Fresnel propagator (accurate within ~ 1 deg, or 17 mrad).

Important: Always provide an initial tilt guess (via hypertune or tutorial notebook: chiahao3/ptyrad). Optimizing tilts from scratch with AD is slow and most likely arrive at barely corrected, slice-shifted object.

The initialized object tilts can be either fixed, hypertuned (global only), or AD-optimized (either global or local) if the learning rate of obj_tilts != 0.

serialize_model()[source]#

Custom serializer to convert pathlib.Path back to str.

pydantic model ptyrad.params.init_params.MeasCalibration[source]#

Bases: BaseModel

Fields:
param mode: Literal['dx', 'dk', 'kMax', 'da', 'angleMax', 'n_alpha', 'RBF', 'fitRBF'] = 'fitRBF'#

Available options for calibration mode, and corresponding units of their value :

  • dx : Ang

  • dk : 1/Ang

  • kMax : 1/Ang

  • da : mrad

  • angleMax : mrad

  • n_alpha : unitless factor (kMax = n_alpha * conv_angle)

  • RBF : px (radius of bright field disk in px)

  • fitRBF : None (default)

Note

real space pixel size and k-space pixel size are directly related via dx = 1/(2*kMax).

param value: float | None = None#

Value used for specific calibration mode. All mode requires a value except for fitRBF, as it fits the radius of bright field disk (RBF) in px, and calibrate it with user-provided conv_angle.

pydantic model ptyrad.params.init_params.ObjOmodeInitOccu[source]#

Bases: BaseModel

Fields:
param occu_type: Literal['uniform', 'custom'] = 'uniform'#

Available options are uniform (default) or custom

  • uniform : Equally split the occupancy to each object mode, meaning each omode would have 1/omode occupancy.

  • custom : Pass in the desired occupancy as an array to init_occu. Note that length(arr) = omode, and sum(arr) = 1.

param init_occu: List[float] | None [Required]#

List of floats that are used to initialize the object mode occupancy if ‘occu_type’ = ‘custom’.

pydantic model ptyrad.params.init_params.MeasPad[source]#

Bases: BaseModel

Fields:
param mode: Literal['on_the_fly', 'precompute'] | None = 'on_the_fly'#

Available options are on_the_fly (default), precompute, or null (will disable padding).

  • precompute : Pad the measurements during initialization, and keep the padded array in memory.

  • on_the_fly : Pad the measurements during optimization, so it’s more efficient for memory.

on_the_fly padding doesn’t really affect the reconstruction time, so it’s suggested to always use on_the_fly to save the memory.

param padding_type: Literal['constant', 'edge', 'linear_ramp', 'exp', 'power'] = 'power'#

Available options are constant, edge, linear_ramp, exp, or power (default).

  • constant : Pad with constant value specified by value

  • edge : Pad with the edge value of the mean diffraction pattern amplitude

  • linear_ramp : Pad with a linear ramp function to go from edge value to the specified value

  • exp: Pad with a background fitted with exponential decay function a * np.exp(-b * r)

  • power: Pad with a background fitted with a power law a * r**-b

If choosing constant or linear_ramp, you’ll need to supply an addition field of value. If using exp or power, the mean diffraction pattern amplitude is used to fit the functional coefficients.

power seems to fit the high angle scattering intensities the best, although padding with constant 0 is also a popular choice.

param target_Npix: int = 256#

Final targeted diffraction pattern size, and it doesn’t need to be power of 2.

param value: float | None = 0#

Amplitude value used for padding background if 'mode'='constant' or 'linear_ramp'.

Since meas_normalization is done before padding, so the supplied value must take the normalization into account.

param threshold: float | None = 70#

Amplitude threshold percentile used for fitting background if 'mode'='power' or 'exp'.

This creates an “exclusion mask” by thresholding the diffraction pattern with values above such percentile threshold. The exclusion mask is used to exclude the contribution from BF disk and strong Bragg disks, so we can fit the background more accurately. Lower threshold value would exclude more values from diffraction pattern, hence less area is left for background fitting.

pydantic model ptyrad.params.init_params.MeasResample[source]#

Bases: BaseModel

Fields:
param mode: Literal['on_the_fly', 'precompute'] | None = 'on_the_fly'#

Available options are on_the_fly (default), precompute, or null (will disable resampling).

  • precompute : Resample the measurements during initialization, and keep the padded array in memory. This is more efficient if you’re “downsampling”.

  • on_the_fly : Resample the measurements during optimization, so it’s more efficient for memory if you’re “upsampling”.

param scale_factors: List[float] = [2, 2]#

List of 2 floats as [ky_zoom, kx_zoom], currently only square detectors are supported, so ky_zoom must be the same as kx_zoom.

pydantic model ptyrad.params.init_params.MeasRemoveNegValues[source]#

Bases: BaseModel

Fields:
param mode: Literal['subtract_min', 'subtract_value', 'clip_neg', 'clip_value'] = 'clip_neg'#

Available options are clip_neg (default), clip_value, subtract_min, subtract_value.

  • clip_neg : Clips the negative value (i.e., setting negative values to 0)

  • clip_value : Clips the pixel intensity below specified value

  • subtract_min : Subtracts the entire dataset by dataset.min if dataset.min < 0

  • subtract_value : Subtracts the entire dataset by specified value

If the dataset array still contains negative values for any reason, a clip_neg correction would be enforced again to guarantee no negative values.

param value: float | None = None#

User-specified intensity value that is used for subtract_value and clip_value modes.

param force: bool = False#

Boolean flag to force executing the MeasRemoveNegValues operation specified in mode.

By default, this non-negative correction is skipped if there’s no negative values in measurements.

Use 'meas_remove_neg_values': {'mode': 'subtract_value', 'value': 20, 'force': true} if you want to force subtract 20 from the entire dataset when there was no negative values.

pydantic model ptyrad.params.init_params.MeasNormalization[source]#

Bases: BaseModel

Fields:
param mode: Literal['max_at_one', 'mean_at_one', 'sum_to_one', 'divide_const'] = 'max_at_one'#

Available options are max_at_one (default), mean_at_one, sum_to_one, and divide_const.

  • max_at_one : Normalize the dataset such that the mean diffraction pattern intensity has a maximum value at 1

  • mean_at_one : Normalize the dataset such that the mean diffraction pattern intensity has a mean value at 1

  • sum_to_one : Normalize the dataset such that the mean diffraction pattern intensity sum to 1

  • divide_const : Normalize the dataset by dividing with the specified value

param value: float | None = None#

User-specified intensity value that is used for divide_const mode.

pydantic model ptyrad.params.init_params.MeasAddPoissonNoise[source]#

Bases: BaseModel

Fields:
param unit: Literal['total_e_per_pattern', 'e_per_Ang2'] [Required]#

Available options are total_e_per_pattern, e-PerAng2.

  • total_e_per_pattern : Applies Poisson noise based on total electron per diffraction pattern

  • e-PerAng2 : Applies Poisson noise based on electron per Angstrom^2

param value: int | float [Required]#

User-specified dose value that is used for total_e_per_pattern or e-PerAng2 modes.

pydantic model ptyrad.params.init_params.MeasExport[source]#

Bases: BaseModel

Fields:
param file_dir: str | None = None#

Sets the output directory.

If {'file_dir': null}, it will export to the same folder as meas_params['path'].

param file_name: str = 'ptyrad_init_meas'#

The output filenamefor the exported measurement array.

param file_format: Literal['hdf5', 'tif', 'npy', 'mat'] = 'hdf5'#

Available options are hdf5, tif, npy, and mat.

Note that the mat is actually HDF5, see https://docs.scipy.org/doc/scipy/reference/generated/scipy.io.savemat.html

param output_shape: List[int] | None = None#

List of integers to reshape the output array like [Ny, Nx, Ky, Kx] or [N_scans, Ky, Kx].

Example:

'meas_export': {'output_shape': [128, 128, 128, 128]}

By default (if None), the output layout is the PtyRAD internal convention (N_scans, Ky, Kx).

param append_shape: bool = True#

If True, it will append the shape of the array to the output file name (e.g., filename_100_100_128_128.h5).

pydantic model ptyrad.params.init_params.ProbeNormalization[source]#

Bases: BaseModel

Fields:
param mode: Literal['mean_total_ints', 'max_total_ints', 'target_intensity'] = 'mean_total_ints'#

Available options are mean_total_ints (default), max_total_ints, and target_intensity.

  • mean_total_ints: Normalizes based on the mean total intensities of measurements.

    probe_int = np.mean(dataset.sum((1,2))) # Sum along (ky, kx)
    
  • max_total_ints: Normalizes by the strongest diffraction pattern intensity (ideally the vacuum region).

    probe_int = np.max(dataset.sum((1,2))) # Sum along (ky, kx)
    
  • target_intensity: Normalizes to a specific value provided in value.

    probe_int = target_intensity
    
param value: float | None = None#

User-specified intensity value that is used for target_intensity mode.

pydantic model ptyrad.params.init_params.ObjZPad[source]#

Bases: BaseModel

Fields:
param pad_layers: List[int | None] = [0, 0]#

A list of 2 integers determining how many layers are appended to the top and bottom surfaces.

Example:

  • [2, 2]: Adds 2 layers on top and 2 layers on the bottom.

  • [0, 5]: Asymmetric padding (only pads 5 layers to the bottom).

param pad_types: List[Literal['vacuum', 'mean', 'edge']] = ['vacuum', 'vacuum']#

A list of 2 strings specifying the content of the padded layers.

Available options are vacuum, mean, edge.

Default is ['vacuum', 'vacuum']

  • vacuum: Fills with empty (vacuum) space

  • mean: Fills with the mean layer of the object

  • edge: Repeats the edge layer values

pydantic model ptyrad.params.init_params.ObjZResample[source]#

Bases: BaseModel

Fields:
param mode: Literal['scale_Nlayer', 'scale_slice_thickness', 'target_Nlayer', 'target_slice_thickness'] [Required]#

Available options:

  • scale_Nlayer : Scales the number of layers

  • scale_slice_thickness : Scales the thickness of each slice

  • target_Nlayer : Resamples to a specific total number of layers

  • target_slice_thickness : Resamples to a specific slice thickness

param value: int | float [Required]#

The numerical value for the operation.

  • Must be a positive integer for target_Nlayer.

  • Must be a positive float for all other modes.

pydantic model ptyrad.params.init_params.TiltParams[source]#

Bases: BaseModel

Fields:
param tilt_type: Literal['all', 'each'] = 'all'#

Determines how the tilt array is initialized.

  • all: Creates a (1, 2) array. All positions share the same global tilt.

  • each: Creates a (N_scans, 2) array. Starts uniform but allows position-dependent optimization (if obj_tilts learning rate > 0).

param init_tilts: List[List[float]] = [[0, 0]]#

[mrad] Initial tilt values [[tilt_y, tilt_x]].

Default is [[0, 0]].

pydantic model ptyrad.params.init_params.FilePathWithKey[source]#

Bases: BaseModel

Fields:
param path: pathlib.Path [Required]#

Absolute or relative path to the data file.

param key: str | None = None#

Internal key path (e.g., for HDF5 or MAT files) to access the specific dataset.

param shape: List[int] | None = None#

Explicit shape of the dataset [N, height, width]. Required when loading binary .raw files (e.g., EMPAD).

param offset: int | None = None#

[bytes] Number of bytes to skip at the beginning of the file. Used for raw binary loading.

param gap: int | None = None#

[bytes] Number of bytes to skip between each diffraction pattern. Used for raw binary loading.

param selection: Any | None = None#

Optional load-time slicing for array-like files, especially HDF5 and Zarr. Use YAML-friendly [start, stop, step] slice specs, e.g. [[0, 64], [0, 64], None, None].

param zarr_kwargs: Dict[str, Any] | None = None#

Optional settings passed to zarr.open. Do not use this for slicing or array path selection; use the top-level selection and key fields.