Skip to content

Parameters

PtyLab.Params

Params

Params

Bases: object

Some settings are shared in between different optimizers, such as the type of propagatorType that you intend to use, if you want to use probe orthogonalization, etc. These are stored in the reconstruction_parameters object.

This ensures that code like this will work as expected:

optimizer1 = optimizers.

Source code in PtyLab/Params/Params.py
class Params(object):
    """
    Some settings are shared in between different optimizers, such as the type of propagatorType that you intend to use,
    if you want to use probe orthogonalization, etc. These are stored in the reconstruction_parameters object.

    This ensures that code like this will work as expected:

    optimizer1 = optimizers.
    """

    def __init__(self):
        # datalogger
        # Total variation regularizerion options
        self.positionCorrectionSwitch_radius = 1
        self.objectTVfreq = 5
        self.objectTVregSwitch = False
        self.objectTVregStepSize = 1e-3

        # other stuff
        self.weigh_probe_updates_by_intensity = False
        self.logger = logging.getLogger("Params")

        # Dump updated object each iteration
        self.dump_obj = False

        # Default settings for switches, settings that involve how things are computed
        self.fftshiftSwitch = False
        # this is an internal setting, tracking wether of not the fftshifts have been done. Do not change this yourself
        self.fftshiftFlag = False
        self.FourierMaskSwitch = False
        self.CPSCswitch = False
        self.CPSCupsamplingFactor = None

        self.intensityConstraint = "standard"  # standard or sigmoid
        self.propagatorType = "Fraunhofer"  # 'Fresnel' 'ASP'
        self.momentumAcceleration = False  # default False, it is turned on in the individual Engines that use momentum
        self.adaptiveMomentumAcceleration = False  # default False, it is turned on in the individual Engines that use momentum

        ## Specific reconstruction settings that are the same for all Engines
        self._gpuSwitch = _check_gpu_availability(verbose=True)
        # This only makes sense on a GPU, not there yet
        self.saveMemory = False
        self.probeUpdateStart = 1
        self.objectUpdateStart = 1
        self.positionOrder = "random"  # 'random' or 'sequential' or 'NA'

        ## Swtiches used in applyConstraints method:
        self.orthogonalizationSwitch = False
        self.orthogonalizationFrequency = 10  # probe orthogonalization frequency
        # object regularization
        self.objectSmoothenessSwitch = False
        self.objectSmoothenessWidth = (
            2  # # pixels over which object is assumed fairly smooth
        )
        self.objectSmoothnessAleph = (
            1e-2  # relaxation constant that determines strength of regularization
        )
        self.absObjectSwitch = False  # force the object to be abs-only
        self.absObjectBeta = 1e-2  # relaxation parameter for abs-only constraint
        self.objectContrastSwitch = False  # pushes object to zero outside ROI
        # probe regularization
        self.probeSmoothenessSwitch = False  # enforce probe smootheness
        self.probeSmoothnessAleph = 5e-2  # relaxation parameter for probe smootheness
        self.probeSmoothenessWidth = 3  # loose object support diameter
        self.probeBoundary = False  # probe cut-off based on a window
        self.absorbingProbeBoundary = (
            False  # controls if probe has period boundary conditions (zero)
        )
        self.absorbingProbeBoundaryAleph = 5e-2
        self.probePowerCorrectionSwitch = False  # probe normalization to measured PSD
        self.probeSpectralPowerCorrectionSwitch = False  # probe normalization from experimentalData.probeSpectralPower
        self.modulusEnforcedProbeSwitch = False  # enforce empty beam

        self.absProbeSwitch = False  # force the probe to be abs-only
        self.absProbeBeta = 1e-2  # relaxation parameter for abs-only constraint
        # other
        self.couplingSwitch = False  # couple adjacent wavelengths
        self.couplingAleph = 50e-2  # couple adjacent wavelengths (relaxation parameter)
        self.binaryProbeSwitch = False  # enforce probe to be binary
        self.binaryProbeThreshold = 0.1  # binarize threshold
        self.binaryProbeAleph = 10e-2  # relaxation parameter for binary constraint
        self.backgroundModeSwitch = False  # background estimate
        self.comStabilizationSwitch = False  # center of mass stabilization for probe
        self.PSDestimationSwitch = False
        self.objectContrastSwitch = False  # pushes object to zero outside ROI
        self.positionCorrectionSwitch = False  # position correction for encoder
        self.adaptiveDenoisingSwitch = (
            False  # estimated noise floor to be clipped from raw data
        )

        self.l2reg = False  # l2 regularisation
        self.l2reg_probe_aleph = 0.01  # strength of the regularizer
        self.l2reg_object_aleph = 0.001

        # autofocusing
        # Wether or not to perform TV autofocusing
        self.TV_autofocus = False
        # what to focus: can be 'TV', 'std', 'min_std', or a callable
        self.TV_autofocus_metric = "TV"
        # Only look at the TV of the intensity as a focusing metric
        self.TV_autofocus_intensityonly = False
        # stepsize
        self.TV_autofocus_stepsize = 5
        # ???
        self.TV_autofocus_aleph = 0.01
        # Region of interest. Can either be in pixels or in a fraction of No/ Np
        self.TV_autofocus_roi = [0.4, 0.6]
        # Propagation range in depths of focus
        self.TV_autofocus_range_dof = 11
        # Friction ot the step algorithm
        self.TV_autofocus_friction = 0.7
        # Shat to focus, can be either 'object' or 'probe'
        self.TV_autofocus_what = "object"
        # only run every run_every iterations
        self.TV_autofocus_run_every = 3
        # minimum distance, set to None for no limit
        self.TV_autofocus_min_z = None
        # maximum distance, set to None for no limit
        self.TV_autofocus_max_z = None
        # number of planes to examine
        self.TV_autofocus_nplanes = 11

        # map a change in positions to a change in z. Experimental, do not use
        self.map_position_to_z_change = False

        self.OPRP = False

        # Default values of all OPR parameters
        # Index of the incoherent probe modes that are linked in a subspace.
        self.OPR_modes = np.array([0])
        # Size of the subspace which is used for the truncated SVD
        self.OPR_subspace = 4
        # Feedback parameter of the OPR modes. The higher the more the probes are allowed
        # to evolve freely. Value range: [0, 1]
        self.OPR_alpha = 0.05
        # Every x iterations the tv constraint is used
        # CURRENTLY not implementd
        self.OPR_tv_freq = 5
        # feedback parameter for the tv constraint
        # CURRENTLY not implementd
        self.OPR_tv = False
        # truncated SVD to chose, either standard numpy svd or randomized tsvd, which
        # saves some computational time
        #   "numpy"      - full SVD, exact, slowest and most memory hungry
        #   "gram"       - rank-k truncation via the (nFrames x nFrames) Gram
        #                  matrix. Same subspace, ~1.8x faster on 4-5x less peak
        #                  memory. The memory saving is the point: it is what
        #                  keeps a large OPR run inside a 32 GB card.
        #   "randomized" - randomized SVD (PtyLab.utils.fsvd.rsvd)
        # Set to "numpy" to reproduce pre-0.3.0 output exactly.
        self.OPR_tsvd_type = "gram"  # numpy, gram or randomized
        # Switch to orthogonolize all incoherent probe modes
        self.OPR_orthogonalize_modes = True
        # Use the batched Gram-matrix form of orthogonalizeIncoherentModes
        # (1.8-4.1x faster). Reproduces the mode powers and the spanned subspace;
        # individual mode vectors may differ from LAPACK's arbitrary choice when
        # two modes carry near-equal power, which measures at 3.1e-05 relative
        # after 30 iterations -- three orders below the algorithm's own
        # sensitivity to its inputs. See PR #96 for the derivation.
        self.OPR_fast_orthogonalization = True
        # If set True only slowly changing probes are allowed
        self.OPR_neighbor_constraint = False

        # SHG stuff
        self.SHG_probe = False

    @property
    def propagator(self):
        """Alias for propagatorType."""
        return self.propagatorType

    @propagator.setter
    def propagator(self, value):
        """Alias for propagatorType."""
        self.propagatorType = value

    @property
    def gpuSwitch(self):
        """Get the GPU switch state."""
        return self._gpuSwitch

    @gpuSwitch.setter
    def gpuSwitch(self, value: bool):
        """Set the GPU switch state with appropriate checks."""
        if value:
            if _check_gpu_availability():
                # if gpuSwitch set to True and GPU is available, either nothing or
                # set again to True if False
                self._gpuSwitch = value
            else:
                msg = "cuda/cupy unavailable or incompatible, cannot set `self.gpuSwitch = True`"
                raise AttributeError(msg)
        else:
            if _check_gpu_availability():
                logger.warning(
                    "Disabling GPU switch. If this is unwanted, please set `self.gpuSwitch = True`"
                )
            else:
                # gpuSwitch is already False and GPU is not available, nothing to do
                pass
            self._gpuSwitch = value
propagator property writable

Alias for propagatorType.

gpuSwitch property writable

Get the GPU switch state.