phenotypic.sdk_.NormControlMixin#

class phenotypic.sdk_.NormControlMixin[source]#

Bases: object

Mixin for operations that need to disable normalization of inner operations.

Provides a method to create copies of ImageEnhancer or ImagePipeline instances with output normalization disabled. This is useful for composite operations where an inner enhancer operates on non-normalized data (e.g., variance-stabilized values from the Generalized Anscombe Transform, typically in the range ~1-32), where clipping or rescaling to [0, 1] would destroy the inverse transform.

The mixin uses duck typing to check for a norm attribute on operations. If an operation has one, the _disable_normalization method will create a shallow copy with norm=None. This preserves the original operation unchanged while allowing the copy to operate without output normalization. Operations that carry no norm field (e.g. BlurGauss) are returned unchanged.

Note

Renamed from ClipControlMixin in 0.18.0, when clip: bool became NormOut. The old name is gone.

Example

Creating a normalization-disabled copy of an enhancer:

>>> from phenotypic.abc_ import ImageEnhancer
>>> from phenotypic.sdk_ import NormalizedOutputMixin, NormControlMixin
>>>
>>> class Denoise(NormalizedOutputMixin, ImageEnhancer):
...     '''Denoise a colony plate.
...
...     Args:
...         sigma: Smoothing width in pixels.
...         norm: Output normalization policy.
...     '''
...
...     sigma: float = 1.0
...
...     def _operate(self, image):
...         return image
>>>
>>> enh = Denoise(sigma=5.0, norm="clip")
>>> copied = NormControlMixin._disable_normalization(enh)
>>> # Original unchanged, copy has norm=None
>>> enh.norm, copied.norm
('clip', None)

Creating a normalization-disabled copy of a pipeline:

>>> from phenotypic import ImagePipeline
>>> from phenotypic.enhance import BlurGauss
>>>
>>> pipeline = ImagePipeline(pipe_cfgs=[
...     BlurGauss(sigma=1.0),
...     Denoise(sigma=5.0, norm="clip")
... ])
>>> copied_pipe = NormControlMixin._disable_normalization(pipeline)
>>> # Only Denoise has a norm attribute, so only it is affected
>>> # _ops is a dict with operation names as keys
>>> [getattr(op, "norm", "absent") for op in copied_pipe._ops.values()]
['absent', None]

Methods

__init__