phenotypic.correction#

Image/grid correction for agar plate captures.

Offers operations that realign grids or correct field-of-view drift so detected colonies stay anchored to their intended wells or pins. The grid aligner adjusts spacing and offsets using reference points or heuristics suited to arrayed plate layouts. Also includes wavelet denoising correctors for full-image noise removal across all components (RGB, gray, detect_mat).

Classes

CaptureMetadata

Camera EXIF recorded from a colour-checker calibration photo.

ColorCheckerProfile

Profile fitted from a colour checker card for root-polynomial correction.

ColorCorrector

Apply root-polynomial color correction using a fitted ColorCheckerProfile.

ColorDenoise

Denoise an RGB plate image using color block-matching 3D filtering (CBM3D).

DenoiseBlockMatch

Denoise the grayscale channel using GAT-stabilized BM3D collaborative filtering.

GridAligner

Correct grid rotation by fitting colony centroids to the target row or column axis.

ImageCropper

Remove pixels from image edges by specifying per-edge crop margins.

ImagePadder

Extend image dimensions by adding pixels to any combination of edges.

BayesShrinkCorrector

Denoise all image components using per-subband adaptive BayesShrink wavelet thresholding.

VisuShrinkCorrector

Denoise all image components using the near-minimax VisuShrink universal wavelet threshold.

class phenotypic.correction.BayesShrinkCorrector(*, use_gat: bool = False, gat_gain: Annotated[float, Gt(gt=0)] = 1.0, gat_mu: Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = 0.0, gat_read_sigma: Annotated[float, Ge(ge=0)] = 0.0, gat_scale_factor: Annotated[float | None, Gt(gt=0)] = None, sigma: Annotated[float | None, TuneSpec(low=0.01, high=0.1, step=None, log=True, categories=None, tunable=True)] = None, wavelet: str = 'db2', mode: Literal['soft', 'hard'] = 'soft', wavelet_levels: Annotated[int | None, TuneSpec(low=2, high=6, step=None, log=False, categories=None, tunable=True)] = None, convert2ycbcr: bool = True, rescale_sigma: bool = True, clip: bool = True)[source]

Bases: _GATSupportMixin, ImageCorrector

Denoise all image components using per-subband adaptive BayesShrink wavelet thresholding.

Apply wavelet denoising to RGB (if present), grayscale, and detection matrix simultaneously. BayesShrink estimates a separate threshold for each wavelet subband from the data, preserving fine colony detail more selectively than the single universal threshold used by VisuShrinkCorrector. All three image representations are updated in a single corrector step, keeping them mutually consistent.

For algorithm details, see What Enhancement Actually Does.

Best For:
  • Plates imaged with aging flatbed scanners or high-ISO cameras that introduce spatially varying sensor noise.

  • RGB plate scans where color composition is subsequently measured and both luminance and chrominance fidelity must be preserved.

  • Filamentous fungi plates where fine hyphal detail is easily erased by overly aggressive universal thresholds.

  • Pre-processing across all channels before multi-channel feature extraction (color composition, morphology, and intensity).

Consider Also:
  • VisuShrinkCorrector when a simpler universal threshold across all subbands is acceptable and speed is a priority.

  • DenoiseBlockMatch when Poisson-Gaussian noise modelling with full BM3D collaborative filtering is preferred over wavelet thresholding.

  • BayesShrinkEnhancer when only the detection matrix should be denoised and RGB and gray must remain untouched.

Parameters:
  • sigma (Annotated[float | None, TuneSpec(low=0.01, high=0.1, step=None, log=True, categories=None, tunable=True)]) – Noise standard deviation on the [0, 1] intensity scale. None auto-estimates from the median absolute deviation of the finest wavelet detail subband (MAD / 0.6745). Typical manual range: 0.01–0.05 for moderate scanner noise, up to 0.1 for heavier noise. Internally retargeted to 1.0 for the gray and detect_mat passes when use_gat=True; RGB is not GAT-wrapped. Default: None.

  • wavelet (str) – PyWavelets wavelet family name. 'db2' (default) balances locality and smoothness; 'db4' has more vanishing moments and wider support, representing smooth colony interiors more sparsely. Default: 'db2'.

  • mode (Literal['soft', 'hard']) – Wavelet coefficient thresholding mode. 'soft' shrinks surviving coefficients toward zero, producing smoother output preferred for detection preprocessing; 'hard' zeroes coefficients below the threshold and leaves the rest unchanged, retaining sharper edges but introducing discontinuities that can appear as ringing near sharp boundaries. Default: 'soft'.

  • wavelet_levels (Annotated[int | None, TuneSpec(low=2, high=6, step=None, log=False, categories=None, tunable=True)]) – Number of wavelet decomposition levels. None uses the library heuristic (maximum possible minus three). Practical manual range: 2–6 for typical plate images. More levels suppress noise at coarser spatial scales; fewer levels restrict denoising to fine-grained noise only. Default: None.

  • convert2ycbcr (bool) – Convert RGB to YCbCr before denoising so luminance and chrominance channels are thresholded independently. Preserves colony hue for pigmentation assays. Applies only when RGB data is present. Default: True.

  • rescale_sigma (bool) – Allow skimage to internally rescale sigma when converting between dtypes. Automatically forced to False during the gray and detect_mat passes when use_gat=True to prevent double-scaling the stabilized-domain noise level. Default: True.

  • clip (bool) – Clamp gray and detect_mat outputs to [0, 1] after denoising. Soft thresholding can produce marginally negative values near dark colony edges; clipping eliminates these. Automatically deferred to False inside the GAT region so the inverse transform operates on the full stabilized signal before the final clamp. Default: True.

  • parameters (# GAT)

  • use_gat (bool) – Wrap gray and detect_mat denoising in the Generalized Anscombe Transform, which converts Poisson-Gaussian noise into approximately unit-variance Gaussian noise so the BayesShrink threshold is correctly scaled. RGB is not transformed. Enable for fluorescence plate readers or low-light incubator images. Default: False.

  • gat_gain (Annotated[float, Gt(gt=0)]) – Camera gain in electrons per ADU. Used by the forward and inverse GAT to scale the Poisson noise component. Typical range: 0.5–10 e-/ADU depending on sensor. Default: 1.0.

  • gat_mu (Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Read-noise mean (dark-current baseline offset) in count units before normalization. Set to 0.0 when the image has already been bias-subtracted, which covers most flatbed-scanner workflows. Default: 0.0.

  • gat_read_sigma (Annotated[float, Ge(ge=0)]) – Read-noise standard deviation in count units consistent with gat_scale_factor. Setting to 0.0 assumes pure Poisson noise; supplying the sensor read-noise spec (a few to a few tens of counts for typical scientific CCDs) improves stabilization in low-signal regions. Default: 0.0.

  • gat_scale_factor (Annotated[float | None, Gt(gt=0)]) – Multiplier converting normalized [0, 1] float data to photon counts before the forward GAT. None auto-detects from image bit depth (8-bit: 255, 16-bit: 65535). Override for non-standard bit depths such as 12-bit sensors (4095). Default: None.

Returns:

Input image with all components (rgb, gray, detect_mat) transformed by adaptive wavelet denoising. All three representations are updated in a single pass.

Return type:

Image

References

[1] S. G. Chang, B. Yu, and M. Vetterli, “Adaptive wavelet thresholding for image denoising and compression,” IEEE Trans. Image Process., vol. 9, no. 9, pp. 1532–1546, Sep. 2000.

[2] D. L. Donoho and I. M. Johnstone, “Ideal spatial adaptation by wavelet shrinkage,” Biometrika, vol. 81, no. 3, pp. 425–455, Sep. 1994.

[3] M. Mäkitalo and A. Foi, “Optimal inversion of the generalized Anscombe transformation for Poisson-Gaussian noise,” IEEE Trans. Image Process., vol. 22, no. 1, pp. 91–103, Jan. 2013.

See also

How To: Denoise Low-Light Images for a visual walkthrough of wavelet denoising on plate images. Image Quality: Noise, Contrast, and Structure for background on noise models and denoising strategy selection.

classmethod __get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler, /) JsonSchemaValue

Hook into generating the model’s JSON schema.

Parameters:
  • core_schema (CoreSchema) – A pydantic-core CoreSchema. You can ignore this argument and call the handler with a new CoreSchema, wrap this CoreSchema ({‘type’: ‘nullable’, ‘schema’: current_schema}), or just call the handler with the original schema.

  • handler (GetJsonSchemaHandler) – Call into Pydantic’s internal JSON schema generation. This will raise a pydantic.errors.PydanticInvalidForJsonSchema if JSON schema generation fails. Since this gets called by BaseModel.model_json_schema you can override the schema_generator argument to that function to change JSON schema generation globally for a type.

Returns:

A JSON schema, as a Python object.

Return type:

JsonSchemaValue

classmethod __pydantic_init_subclass__(**kwargs: Any) None

Populate field descriptions from the subclass docstring.

Runs once per concrete subclass after pydantic has built its model. Copies parameter descriptions parsed from the Google-style Args: docstring block onto each field’s description slot so they surface in model_json_schema() — the machine-readable contract used by downstream tooling (e.g. an MCP server).

Parameters:

**kwargs (Any) – Class-keyword arguments forwarded by pydantic.

Return type:

None

classmethod __pydantic_on_complete__() None

This is called once the class and its fields are fully initialized and ready to be used.

This typically happens when the class is created (just before [__pydantic_init_subclass__()][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass), except when forward annotations are used that could not immediately be resolved. In that case, it will be called later, when the model is rebuilt automatically or explicitly using [model_rebuild()][pydantic.main.BaseModel.model_rebuild].

Return type:

None

classmethod construct(_fields_set: set[str] | None = None, **values: Any) Self
Parameters:
Return type:

Self

classmethod from_json(json_data: str | Path | dict) BaseOperation

Reconstruct an operation from JSON written by to_json().

Accepts a JSON string, a path to a JSON file, or a pre-parsed envelope dict (same input handling as ImagePipeline.from_json()). Polymorphic: ImageOperation.from_json(path) returns whatever concrete operation the file holds. When called on a narrower subclass, the resolved class must be a subclass of it, else a TypeError is raised.

Parameters:

json_data (str | Path | dict) – A JSON string, path to a JSON file, or envelope dict.

Returns:

The reconstructed operation instance.

Raises:
  • AttributeError – If the recorded class cannot be resolved in the phenotypic namespace.

  • TypeError – If called on a concrete subclass and the file holds a class that is not a subclass of it.

Return type:

BaseOperation

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.abc_ import ImageOperation
>>> from phenotypic.detect import OtsuDetector
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     OtsuDetector().to_json(p)
...     loaded = ImageOperation.from_json(p)  # polymorphic
>>> type(loaded).__name__
'OtsuDetector'
classmethod from_orm(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod model_construct(_fields_set: set[str] | None = None, **values: Any) Self

Creates a new instance of the Model class with validated data.

Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed.

!!! note

model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == ‘allow’, then all extra passed values are added to the model instance’s __dict__ and __pydantic_extra__ fields. If model_config.extra == ‘ignore’ (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == ‘forbid’ does not result in an error if extra values are passed, but they will be ignored.

Parameters:
  • _fields_set (set[str] | None) – A set of field names that were originally explicitly set during instantiation. If provided, this is directly used for the [model_fields_set][pydantic.BaseModel.model_fields_set] attribute. Otherwise, the field names from the values argument will be used.

  • values (Any) – Trusted or pre-validated data dictionary.

Returns:

A new instance of the Model class with validated data.

Return type:

Self

classmethod model_json_schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}', schema_generator: type[~pydantic.json_schema.GenerateJsonSchema] = <class 'pydantic.json_schema.GenerateJsonSchema'>, mode: ~typing.Literal['validation', 'serialization'] = 'validation', *, union_format: ~typing.Literal['any_of', 'primitive_type_array'] = 'any_of') dict[str, Any]

Generates a JSON schema for a model class.

Parameters:
  • by_alias (bool) – Whether to use attribute aliases or not.

  • ref_template (str) – The reference template.

  • union_format (Literal['any_of', 'primitive_type_array']) –

    The format to use when combining schemas from unions together. Can be one of:

    keyword to combine schemas (the default). - ‘primitive_type_array’: Use the [type](https://json-schema.org/understanding-json-schema/reference/type) keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive type (string, boolean, null, integer or number) or contains constraints/metadata, falls back to any_of.

  • schema_generator (type[GenerateJsonSchema]) – To override the logic used to generate the JSON schema, as a subclass of GenerateJsonSchema with your desired modifications

  • mode (Literal['validation', 'serialization']) – The mode in which to generate the schema.

Returns:

The JSON schema for the given model class.

Return type:

dict[str, Any]

classmethod model_parametrized_name(params: tuple[type[Any], ...]) str

Compute the class name for parametrizations of generic classes.

This method can be overridden to achieve a custom naming scheme for generic BaseModels.

Parameters:

params (tuple[type[Any], ...]) – Tuple of types of the class. Given a generic class Model with 2 type variables and a concrete model Model[str, int], the value (str, int) would be passed to params.

Returns:

String representing the new class where params are passed to cls as type variables.

Raises:

TypeError – Raised when trying to generate concrete names for non-generic models.

Return type:

str

classmethod model_rebuild(*, force: bool = False, raise_errors: bool = True, _parent_namespace_depth: int = 2, _types_namespace: MappingNamespace | None = None) bool | None

Try to rebuild the pydantic-core schema for the model.

This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.

Parameters:
  • force (bool) – Whether to force the rebuilding of the model schema, defaults to False.

  • raise_errors (bool) – Whether to raise errors, defaults to True.

  • _parent_namespace_depth (int) – The depth level of the parent namespace, defaults to 2.

  • _types_namespace (MappingNamespace | None) – The types namespace, defaults to None.

Returns:

Returns None if the schema is already “complete” and rebuilding was not required. If rebuilding _was_ required, returns True if rebuilding was successful, otherwise False.

Return type:

bool | None

classmethod model_validate(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, from_attributes: bool | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate a pydantic model instance.

Parameters:
  • obj (Any) – The object to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • from_attributes (bool | None) – Whether to extract data from object attributes.

  • context (Any | None) – Additional context to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Raises:

ValidationError – If the object could not be validated.

Returns:

The validated model instance.

Return type:

Self

classmethod model_validate_json(json_data: str | bytes | bytearray, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self
!!! abstract “Usage Documentation”

[JSON Parsing](../concepts/json.md#json-parsing)

Validate the given JSON data against the Pydantic model.

Parameters:
  • json_data (str | bytes | bytearray) – The JSON data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Raises:

ValidationError – If json_data is not a JSON string or the object could not be validated.

Return type:

Self

classmethod model_validate_strings(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate the given object with string data against the Pydantic model.

Parameters:
  • obj (Any) – The object containing string data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Return type:

Self

classmethod parse_file(path: str | Path, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • path (str | Path)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod parse_obj(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod parse_raw(b: str | bytes, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • b (str | bytes)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}') Dict[str, Any]
Parameters:
  • by_alias (bool)

  • ref_template (str)

Return type:

Dict[str, Any]

classmethod schema_json(*, by_alias: bool = True, ref_template: str = '#/$defs/{model}', **dumps_kwargs: Any) str
Parameters:
  • by_alias (bool)

  • ref_template (str)

  • dumps_kwargs (Any)

Return type:

str

classmethod update_forward_refs(**localns: Any) None
Parameters:

localns (Any)

Return type:

None

classmethod validate(value: Any) Self
Parameters:

value (Any)

Return type:

Self

__copy__() Self

Returns a shallow copy of the model.

Return type:

Self

__deepcopy__(memo: dict[int, Any] | None = None) Self

Returns a deep copy of the model.

Parameters:

memo (dict[int, Any] | None)

Return type:

Self

__del__()

Automatically stop tracemalloc when the object is deleted.

__init__(**data: Any) None

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:

data (Any)

Return type:

None

__iter__() Generator[tuple[str, Any], None, None]

So dict(model) works.

Return type:

Generator[tuple[str, Any], None, None]

__pretty__(fmt: Callable[[Any], Any], **kwargs: Any) Generator[Any]

Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects.

Parameters:
Return type:

Generator[Any]

__repr_name__() str

Name of the instance’s class, used in __repr__.

Return type:

str

__repr_recursion__(object: Any) str

Returns the string representation of a recursive object.

Parameters:

object (Any)

Return type:

str

__rich_repr__() RichReprResult

Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects.

Return type:

RichReprResult

apply(image: Image, inplace: bool = False) Image

Applies the operation to an image, either in-place or on a copy.

Parameters:
  • image (Image) – The arr image to apply the operation on.

  • inplace (bool) – If True, modifies the image in place; otherwise, operates on a copy of the image.

Returns:

The modified image after applying the operation.

Return type:

Image

copy(*, include: AbstractSetIntStr | MappingIntStrAny | None = None, exclude: AbstractSetIntStr | MappingIntStrAny | None = None, update: Dict[str, Any] | None = None, deep: bool = False) Self

Returns a copy of the model.

!!! warning “Deprecated”

This method is now deprecated; use model_copy instead.

If you need include or exclude, use:

`python {test="skip" lint="skip"} data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = {**data, **(update or {})} copied = self.model_validate(data) `

Parameters:
  • include (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to include in the copied model.

  • exclude (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to exclude in the copied model.

  • update (Dict[str, Any] | None) – Optional dictionary of field-value pairs to override field values in the copied model.

  • deep (bool) – If True, the values of fields that are Pydantic models will be deep-copied.

Returns:

A copy of the model with included, excluded and updated fields as specified.

Return type:

Self

dict(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False) Dict[str, Any]
Parameters:
Return type:

Dict[str, Any]

json(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Callable[[Any], Any] | None = PydanticUndefined, models_as_dict: bool = PydanticUndefined, **dumps_kwargs: Any) str
Parameters:
Return type:

str

model_copy(*, update: Mapping[str, Any] | None = None, deep: bool = False) Self
!!! abstract “Usage Documentation”

[model_copy](../concepts/models.md#model-copy)

Returns a copy of the model.

!!! note

The underlying instance’s [__dict__][object.__dict__] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).

Parameters:
  • update (Mapping[str, Any] | None) – Values to change/add in the new model. Note: the data is not validated before creating the new model. You should trust this data.

  • deep (bool) – Set to True to make a deep copy of the model.

Returns:

New model instance.

Return type:

Self

model_dump(*, mode: Literal['json', 'python'] | str = 'python', include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) dict[str, Any]
!!! abstract “Usage Documentation”

[model_dump](../concepts/serialization.md#python-mode)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Parameters:
  • mode (Literal['json', 'python'] | str) – The mode in which to_python should run. If mode is ‘json’, the output will only contain JSON serializable types. If mode is ‘python’, the output may contain non-JSON-serializable Python objects.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to include in the output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to exclude from the output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to use the field’s alias in the dictionary key if defined.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A dictionary representation of the model.

Return type:

dict[str, Any]

model_dump_json(*, indent: int | None = None, ensure_ascii: bool = False, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) str
!!! abstract “Usage Documentation”

[model_dump_json](../concepts/serialization.md#json-mode)

Generates a JSON representation of the model using Pydantic’s to_json method.

Parameters:
  • indent (int | None) – Indentation to use in the JSON output. If None is passed, the output will be compact.

  • ensure_ascii (bool) – If True, the output is guaranteed to have all incoming non-ASCII characters escaped. If False (the default), these characters will be output as-is.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to include in the JSON output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to exclude from the JSON output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to serialize using field aliases.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A JSON string representation of the model.

Return type:

str

model_post_init(_BaseOperation__context: Any) None

Initialize logging and memory tracking after model construction.

Replaces the legacy __init__ body: creates the per-class logger and, when that logger is enabled for INFO level or higher, starts tracemalloc so per-operation memory usage can be logged.

Parameters:
  • __context – Pydantic post-init context (unused).

  • _BaseOperation__context (Any)

Return type:

None

to_json(filepath: str | Path | None = None) str | None

Serialize this operation to JSON.

Captures the operation as a {"class", "params"} envelope: params is model_dump(mode="json") (every declared field, including nested operations and raw arrays; PrivateAttr state such as loggers and timing is excluded automatically), and class records the concrete class name so from_json() can rebuild the right subclass. This mirrors ImagePipeline.to_json().

Parameters:

filepath (str | Path | None) – Optional path to write the JSON to. When None, the JSON string is returned instead. Accepts a str or Path.

Returns:

The JSON string when filepath is None, otherwise None.

Return type:

str | None

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.detect import OtsuDetector
>>> from phenotypic.sdk_ import CONFIG_SUFFIX_OPERATION, ensure_typed_json_suffix
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     saved = ensure_typed_json_suffix(p, CONFIG_SUFFIX_OPERATION)
...     OtsuDetector(ignore_zeros=True).to_json(p)
...     loaded = OtsuDetector.from_json(saved)
>>> loaded.ignore_zeros
True
widget(image: Image | None = None, show: bool = False) Widget

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.

clip: bool
convert2ycbcr: bool
gat_gain: float
gat_mu: Annotated[float, TuneSpec(tunable=False)]
gat_read_sigma: float
gat_scale_factor: float | None
mode: Literal['soft', 'hard']
model_computed_fields = {}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_extra: dict[str, Any] | None

Get extra fields set during validation.

Returns:

A dictionary of extra fields, or None if config.extra is not set to “allow”.

model_fields = {'clip': FieldInfo(annotation=bool, required=False, default=True, description='Clamp gray and detect_mat outputs to [0, 1] after denoising. Soft thresholding can produce marginally negative values near dark colony edges; clipping eliminates these. Automatically deferred to ``False`` inside the GAT region so the inverse transform operates on the full stabilized signal before the final clamp. Default: ``True``. # GAT parameters (active only when use_gat=True)'), 'convert2ycbcr': FieldInfo(annotation=bool, required=False, default=True, description='Convert RGB to YCbCr before denoising so luminance and chrominance channels are thresholded independently. Preserves colony hue for pigmentation assays. Applies only when RGB data is present. Default: ``True``.'), 'gat_gain': FieldInfo(annotation=float, required=False, default=1.0, description='Camera gain in electrons per ADU. Used by the forward and inverse GAT to scale the Poisson noise component. Typical range: 0.5--10 e-/ADU depending on sensor. Default: ``1.0``.', metadata=[Gt(gt=0)]), 'gat_mu': FieldInfo(annotation=float, required=False, default=0.0, description='Read-noise mean (dark-current baseline offset) in count units before normalization. Set to 0.0 when the image has already been bias-subtracted, which covers most flatbed-scanner workflows.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'gat_read_sigma': FieldInfo(annotation=float, required=False, default=0.0, description='Read-noise standard deviation in count units consistent with ``gat_scale_factor``. Setting to 0.0 assumes pure Poisson noise; supplying the sensor read-noise spec (a few to a few tens of counts for typical scientific CCDs) improves stabilization in low-signal regions. Default: ``0.0``.', metadata=[Ge(ge=0)]), 'gat_scale_factor': FieldInfo(annotation=Union[float, NoneType], required=False, default=None, description='Multiplier converting normalized [0, 1] float data to photon counts before the forward GAT. ``None`` auto-detects from image bit depth (8-bit: 255, 16-bit: 65535). Override for non-standard bit depths such as 12-bit sensors (4095). Default: ``None``.', metadata=[Gt(gt=0)]), 'mode': FieldInfo(annotation=Literal['soft', 'hard'], required=False, default='soft', description="Wavelet coefficient thresholding mode. ``'soft'`` shrinks surviving coefficients toward zero, producing smoother output preferred for detection preprocessing; ``'hard'`` zeroes coefficients below the threshold and leaves the rest unchanged, retaining sharper edges but introducing discontinuities that can appear as ringing near sharp boundaries. Default: ``'soft'``."), 'rescale_sigma': FieldInfo(annotation=bool, required=False, default=True, description='Allow skimage to internally rescale sigma when converting between dtypes. Automatically forced to ``False`` during the gray and detect_mat passes when ``use_gat=True`` to prevent double-scaling the stabilized-domain noise level. Default: ``True``.'), 'sigma': FieldInfo(annotation=Union[float, NoneType], required=False, default=None, description='Noise standard deviation on the [0, 1] intensity scale. ``None`` auto-estimates from the median absolute deviation of the finest wavelet detail subband (MAD / 0.6745). Typical manual range: 0.01--0.05 for moderate scanner noise, up to 0.1 for heavier noise. Internally retargeted to 1.0 for the gray and detect_mat passes when ``use_gat=True``; RGB is not GAT-wrapped. Default: ``None``.', metadata=[TuneSpec(low=0.01, high=0.1, step=None, log=True, categories=None, tunable=True)]), 'use_gat': FieldInfo(annotation=bool, required=False, default=False, description='Wrap gray and detect_mat denoising in the Generalized Anscombe Transform, which converts Poisson-Gaussian noise into approximately unit-variance Gaussian noise so the BayesShrink threshold is correctly scaled. RGB is not transformed. Enable for fluorescence plate readers or low-light incubator images.'), 'wavelet': FieldInfo(annotation=str, required=False, default='db2', description="PyWavelets wavelet family name. ``'db2'`` (default) balances locality and smoothness; ``'db4'`` has more vanishing moments and wider support, representing smooth colony interiors more sparsely."), 'wavelet_levels': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, description='Number of wavelet decomposition levels. ``None`` uses the library heuristic (maximum possible minus three). Practical manual range: 2--6 for typical plate images. More levels suppress noise at coarser spatial scales; fewer levels restrict denoising to fine-grained noise only. Default: ``None``.', metadata=[TuneSpec(low=2, high=6, step=None, log=False, categories=None, tunable=True)])}
property model_fields_set: set[str]

Returns the set of fields that have been explicitly set on this model instance.

Returns:

A set of strings representing the fields that have been set,

i.e. that were not filled from defaults.

rescale_sigma: bool
sigma: Annotated[float | None, TuneSpec(0.01, 0.1, log=True)]
use_gat: bool
wavelet: str
wavelet_levels: Annotated[int | None, TuneSpec(2, 6)]
class phenotypic.correction.CaptureMetadata(*, camera_make: str | None = None, camera_model: str | None = None, lens_model: str | None = None, iso: Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None, exposure_time: Annotated[float | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None, f_number: Annotated[float | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None, focal_length: Annotated[float | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None)[source]

Bases: BaseModel

Camera EXIF recorded from a colour-checker calibration photo.

Populated by from_image() at ColorCheckerProfile.fit() time and compared against corrected images by ColorCorrector via compare(). Every field is optional: tags absent from the source image (or images read without EXIF) remain None and are skipped during comparison.

Parameters:
  • camera_make (str | None)

  • camera_model (str | None)

  • lens_model (str | None)

  • iso (Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)])

  • exposure_time (Annotated[float | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)])

  • f_number (Annotated[float | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)])

  • focal_length (Annotated[float | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)])

camera_make

Camera manufacturer (EXIF Make).

Type:

str | None

camera_model

Camera body model (EXIF Model).

Type:

str | None

lens_model

Lens model (EXIF LensModel / LensID).

Type:

str | None

iso

ISO sensitivity (EXIF ISO / ISOSpeedRatings).

Type:

int | None

exposure_time

Exposure time in seconds (EXIF ExposureTime).

Type:

float | None

f_number

Aperture F-number (EXIF FNumber).

Type:

float | None

focal_length

Focal length in millimetres (EXIF FocalLength).

Type:

float | None

Examples

Differences are split into camera-identity (critical) and exposure-setting (informational) buckets:

>>> a = CaptureMetadata(
...     camera_model="Canon EOS R100", lens_model="RF 50mm", iso=800
... )
>>> b = CaptureMetadata(
...     camera_model="Canon EOS R5", lens_model="RF 50mm", iso=400
... )
>>> critical, informational = a.compare(b)
>>> critical
["camera_model (profile='Canon EOS R100', image='Canon EOS R5')"]
>>> informational
['iso (profile=800, image=400)']
classmethod __get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler, /) JsonSchemaValue

Hook into generating the model’s JSON schema.

Parameters:
  • core_schema (CoreSchema) – A pydantic-core CoreSchema. You can ignore this argument and call the handler with a new CoreSchema, wrap this CoreSchema ({‘type’: ‘nullable’, ‘schema’: current_schema}), or just call the handler with the original schema.

  • handler (GetJsonSchemaHandler) – Call into Pydantic’s internal JSON schema generation. This will raise a pydantic.errors.PydanticInvalidForJsonSchema if JSON schema generation fails. Since this gets called by BaseModel.model_json_schema you can override the schema_generator argument to that function to change JSON schema generation globally for a type.

Returns:

A JSON schema, as a Python object.

Return type:

JsonSchemaValue

classmethod __pydantic_init_subclass__(**kwargs: Any) None

This is intended to behave just like __init_subclass__, but is called by ModelMetaclass only after basic class initialization is complete. In particular, attributes like model_fields will be present when this is called, but forward annotations are not guaranteed to be resolved yet, meaning that creating an instance of the class may fail.

This is necessary because __init_subclass__ will always be called by type.__new__, and it would require a prohibitively large refactor to the ModelMetaclass to ensure that type.__new__ was called in such a manner that the class would already be sufficiently initialized.

This will receive the same kwargs that would be passed to the standard __init_subclass__, namely, any kwargs passed to the class definition that aren’t used internally by Pydantic.

Parameters:

**kwargs (Any) – Any keyword arguments passed to the class definition that aren’t used internally by Pydantic.

Return type:

None

Note

You may want to override [__pydantic_on_complete__()][pydantic.main.BaseModel.__pydantic_on_complete__] instead, which is called once the class and its fields are fully initialized and ready for validation.

classmethod __pydantic_on_complete__() None

This is called once the class and its fields are fully initialized and ready to be used.

This typically happens when the class is created (just before [__pydantic_init_subclass__()][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass), except when forward annotations are used that could not immediately be resolved. In that case, it will be called later, when the model is rebuilt automatically or explicitly using [model_rebuild()][pydantic.main.BaseModel.model_rebuild].

Return type:

None

classmethod construct(_fields_set: set[str] | None = None, **values: Any) Self
Parameters:
Return type:

Self

classmethod from_image(image: Image) CaptureMetadata[source]

Extract capture metadata from an image’s EXIF.

Reads the image’s imported metadata (where imread deposits EXIF) with precedence, then falls back to the public image.metadata view for any manually-set keys. Keys are normalised via _normalize_key() so the canonical tag is found regardless of the reader’s prefix/spelling.

Parameters:

image (Image) – Source image, ideally read via Image.imread() so EXIF is present.

Returns:

A populated CaptureMetadata; fields with no matching EXIF tag are left None.

Return type:

CaptureMetadata

classmethod from_orm(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod model_construct(_fields_set: set[str] | None = None, **values: Any) Self

Creates a new instance of the Model class with validated data.

Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed.

!!! note

model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == ‘allow’, then all extra passed values are added to the model instance’s __dict__ and __pydantic_extra__ fields. If model_config.extra == ‘ignore’ (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == ‘forbid’ does not result in an error if extra values are passed, but they will be ignored.

Parameters:
  • _fields_set (set[str] | None) – A set of field names that were originally explicitly set during instantiation. If provided, this is directly used for the [model_fields_set][pydantic.BaseModel.model_fields_set] attribute. Otherwise, the field names from the values argument will be used.

  • values (Any) – Trusted or pre-validated data dictionary.

Returns:

A new instance of the Model class with validated data.

Return type:

Self

classmethod model_json_schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}', schema_generator: type[~pydantic.json_schema.GenerateJsonSchema] = <class 'pydantic.json_schema.GenerateJsonSchema'>, mode: ~typing.Literal['validation', 'serialization'] = 'validation', *, union_format: ~typing.Literal['any_of', 'primitive_type_array'] = 'any_of') dict[str, Any]

Generates a JSON schema for a model class.

Parameters:
  • by_alias (bool) – Whether to use attribute aliases or not.

  • ref_template (str) – The reference template.

  • union_format (Literal['any_of', 'primitive_type_array']) –

    The format to use when combining schemas from unions together. Can be one of:

    keyword to combine schemas (the default). - ‘primitive_type_array’: Use the [type](https://json-schema.org/understanding-json-schema/reference/type) keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive type (string, boolean, null, integer or number) or contains constraints/metadata, falls back to any_of.

  • schema_generator (type[GenerateJsonSchema]) – To override the logic used to generate the JSON schema, as a subclass of GenerateJsonSchema with your desired modifications

  • mode (Literal['validation', 'serialization']) – The mode in which to generate the schema.

Returns:

The JSON schema for the given model class.

Return type:

dict[str, Any]

classmethod model_parametrized_name(params: tuple[type[Any], ...]) str

Compute the class name for parametrizations of generic classes.

This method can be overridden to achieve a custom naming scheme for generic BaseModels.

Parameters:

params (tuple[type[Any], ...]) – Tuple of types of the class. Given a generic class Model with 2 type variables and a concrete model Model[str, int], the value (str, int) would be passed to params.

Returns:

String representing the new class where params are passed to cls as type variables.

Raises:

TypeError – Raised when trying to generate concrete names for non-generic models.

Return type:

str

classmethod model_rebuild(*, force: bool = False, raise_errors: bool = True, _parent_namespace_depth: int = 2, _types_namespace: MappingNamespace | None = None) bool | None

Try to rebuild the pydantic-core schema for the model.

This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.

Parameters:
  • force (bool) – Whether to force the rebuilding of the model schema, defaults to False.

  • raise_errors (bool) – Whether to raise errors, defaults to True.

  • _parent_namespace_depth (int) – The depth level of the parent namespace, defaults to 2.

  • _types_namespace (MappingNamespace | None) – The types namespace, defaults to None.

Returns:

Returns None if the schema is already “complete” and rebuilding was not required. If rebuilding _was_ required, returns True if rebuilding was successful, otherwise False.

Return type:

bool | None

classmethod model_validate(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, from_attributes: bool | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate a pydantic model instance.

Parameters:
  • obj (Any) – The object to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • from_attributes (bool | None) – Whether to extract data from object attributes.

  • context (Any | None) – Additional context to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Raises:

ValidationError – If the object could not be validated.

Returns:

The validated model instance.

Return type:

Self

classmethod model_validate_json(json_data: str | bytes | bytearray, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self
!!! abstract “Usage Documentation”

[JSON Parsing](../concepts/json.md#json-parsing)

Validate the given JSON data against the Pydantic model.

Parameters:
  • json_data (str | bytes | bytearray) – The JSON data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Raises:

ValidationError – If json_data is not a JSON string or the object could not be validated.

Return type:

Self

classmethod model_validate_strings(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate the given object with string data against the Pydantic model.

Parameters:
  • obj (Any) – The object containing string data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Return type:

Self

classmethod parse_file(path: str | Path, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • path (str | Path)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod parse_obj(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod parse_raw(b: str | bytes, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • b (str | bytes)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}') Dict[str, Any]
Parameters:
  • by_alias (bool)

  • ref_template (str)

Return type:

Dict[str, Any]

classmethod schema_json(*, by_alias: bool = True, ref_template: str = '#/$defs/{model}', **dumps_kwargs: Any) str
Parameters:
  • by_alias (bool)

  • ref_template (str)

  • dumps_kwargs (Any)

Return type:

str

classmethod update_forward_refs(**localns: Any) None
Parameters:

localns (Any)

Return type:

None

classmethod validate(value: Any) Self
Parameters:

value (Any)

Return type:

Self

__copy__() Self

Returns a shallow copy of the model.

Return type:

Self

__deepcopy__(memo: dict[int, Any] | None = None) Self

Returns a deep copy of the model.

Parameters:

memo (dict[int, Any] | None)

Return type:

Self

__init__(**data: Any) None

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:

data (Any)

Return type:

None

__iter__() Generator[tuple[str, Any], None, None]

So dict(model) works.

Return type:

Generator[tuple[str, Any], None, None]

__pretty__(fmt: Callable[[Any], Any], **kwargs: Any) Generator[Any]

Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects.

Parameters:
Return type:

Generator[Any]

__repr_name__() str

Name of the instance’s class, used in __repr__.

Return type:

str

__repr_recursion__(object: Any) str

Returns the string representation of a recursive object.

Parameters:

object (Any)

Return type:

str

__rich_repr__() RichReprResult

Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects.

Return type:

RichReprResult

compare(other: CaptureMetadata) tuple[list[str], list[str]][source]

Diff this metadata against another, bucketed by severity.

A field is only compared when it is non-None on both sides, so an EXIF-less target image never generates spurious differences.

Parameters:

other (CaptureMetadata) – Metadata to compare against (typically extracted from the image being corrected).

Returns:

A (critical, informational) tuple of human-readable diff strings. critical covers camera/lens identity; informational covers ISO/exposure/aperture/focal length.

Return type:

tuple[list[str], list[str]]

copy(*, include: AbstractSetIntStr | MappingIntStrAny | None = None, exclude: AbstractSetIntStr | MappingIntStrAny | None = None, update: Dict[str, Any] | None = None, deep: bool = False) Self

Returns a copy of the model.

!!! warning “Deprecated”

This method is now deprecated; use model_copy instead.

If you need include or exclude, use:

`python {test="skip" lint="skip"} data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = {**data, **(update or {})} copied = self.model_validate(data) `

Parameters:
  • include (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to include in the copied model.

  • exclude (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to exclude in the copied model.

  • update (Dict[str, Any] | None) – Optional dictionary of field-value pairs to override field values in the copied model.

  • deep (bool) – If True, the values of fields that are Pydantic models will be deep-copied.

Returns:

A copy of the model with included, excluded and updated fields as specified.

Return type:

Self

dict(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False) Dict[str, Any]
Parameters:
Return type:

Dict[str, Any]

json(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Callable[[Any], Any] | None = PydanticUndefined, models_as_dict: bool = PydanticUndefined, **dumps_kwargs: Any) str
Parameters:
Return type:

str

model_copy(*, update: Mapping[str, Any] | None = None, deep: bool = False) Self
!!! abstract “Usage Documentation”

[model_copy](../concepts/models.md#model-copy)

Returns a copy of the model.

!!! note

The underlying instance’s [__dict__][object.__dict__] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).

Parameters:
  • update (Mapping[str, Any] | None) – Values to change/add in the new model. Note: the data is not validated before creating the new model. You should trust this data.

  • deep (bool) – Set to True to make a deep copy of the model.

Returns:

New model instance.

Return type:

Self

model_dump(*, mode: Literal['json', 'python'] | str = 'python', include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) dict[str, Any]
!!! abstract “Usage Documentation”

[model_dump](../concepts/serialization.md#python-mode)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Parameters:
  • mode (Literal['json', 'python'] | str) – The mode in which to_python should run. If mode is ‘json’, the output will only contain JSON serializable types. If mode is ‘python’, the output may contain non-JSON-serializable Python objects.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to include in the output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to exclude from the output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to use the field’s alias in the dictionary key if defined.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A dictionary representation of the model.

Return type:

dict[str, Any]

model_dump_json(*, indent: int | None = None, ensure_ascii: bool = False, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) str
!!! abstract “Usage Documentation”

[model_dump_json](../concepts/serialization.md#json-mode)

Generates a JSON representation of the model using Pydantic’s to_json method.

Parameters:
  • indent (int | None) – Indentation to use in the JSON output. If None is passed, the output will be compact.

  • ensure_ascii (bool) – If True, the output is guaranteed to have all incoming non-ASCII characters escaped. If False (the default), these characters will be output as-is.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to include in the JSON output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to exclude from the JSON output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to serialize using field aliases.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A JSON string representation of the model.

Return type:

str

model_post_init(context: Any, /) None

Override this method to perform additional initialization after __init__ and model_construct. This is useful if you want to do some validation that requires the entire model to be initialized.

Parameters:

context (Any)

Return type:

None

camera_make: str | None
camera_model: str | None
exposure_time: Annotated[float | None, TuneSpec(tunable=False)]
f_number: Annotated[float | None, TuneSpec(tunable=False)]
focal_length: Annotated[float | None, TuneSpec(tunable=False)]
iso: Annotated[int | None, TuneSpec(tunable=False)]
lens_model: str | None
model_computed_fields = {}
model_config: ClassVar[ConfigDict] = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_extra: dict[str, Any] | None

Get extra fields set during validation.

Returns:

A dictionary of extra fields, or None if config.extra is not set to “allow”.

model_fields = {'camera_make': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'camera_model': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'exposure_time': FieldInfo(annotation=Union[float, NoneType], required=False, default=None, metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'f_number': FieldInfo(annotation=Union[float, NoneType], required=False, default=None, metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'focal_length': FieldInfo(annotation=Union[float, NoneType], required=False, default=None, metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'iso': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'lens_model': FieldInfo(annotation=Union[str, NoneType], required=False, default=None)}
property model_fields_set: set[str]

Returns the set of fields that have been explicitly set on this model instance.

Returns:

A set of strings representing the fields that have been set,

i.e. that were not filled from defaults.

class phenotypic.correction.ColorCheckerProfile(*, checker_type: str = 'ColorChecker24 - After November 2014', degree: Annotated[int, TuneSpec(low=None, high=None, step=None, log=False, categories=1, 2, 3, 4, tunable=True)] = 2, target_illuminant: str = 'D65', median_filter_size: int = 10, stddev_mag_threshold: float = 15.0, pad_checker: bool = False, min_swatch_area_frac: Annotated[float, TuneSpec(low=0.1, high=0.6, step=None, log=False, categories=None, tunable=True)] = 0.3, core_fraction: Annotated[float, TuneSpec(low=0.3, high=0.8, step=None, log=False, categories=None, tunable=True)] = 0.5, ridge_lambda: Annotated[float, TuneSpec(low=0.0001, high=0.1, step=None, log=True, categories=None, tunable=True)] = 0.001, outlier_sigma: Annotated[float, TuneSpec(low=1.5, high=4.0, step=None, log=False, categories=None, tunable=True)] = 2.0, rois: list[tuple[~typing.Annotated[slice, ~pydantic.json_schema.WithJsonSchema(json_schema={'type': 'object', 'description': 'A Python slice (start, stop, step) bounding a color-checker ROI along one image axis.'}, mode=None)], ~typing.Annotated[slice, ~pydantic.json_schema.WithJsonSchema(json_schema={'type': 'object', 'description': 'A Python slice (start, stop, step) bounding a color-checker ROI along one image axis.'}, mode=None)]]] | None = None, correction_matrix: WithJsonSchema(json_schema={'type': 'array', 'items': {}}, mode=None)] | None = None, diagnostics: dict[str, Any] = {}, is_fitted: bool = False, capture_metadata: CaptureMetadata | None = None)[source]

Bases: BaseModel

Profile fitted from a colour checker card for root-polynomial correction.

Measures patch colours from one or more ROIs in an image, matches them against published reference values for the chosen checker type, rejects outlier patches, and solves for a root-polynomial colour correction matrix (Finlayson 2015). The resulting matrix can be applied to entire images via ColorCorrector.

This is a pydantic v2 BaseModel: the constructor parameters and the post-fit state are declared as annotated class-level fields, so an unfitted profile still constructs (correction_matrix is None, is_fitted is False until fit() runs).

Parameters:
  • checker_type (str) – Key in colour.CCS_COLOURCHECKERS. Defaults to the post-2014 X-Rite ColorChecker 24.

  • degree (Annotated[int, TuneSpec(low=None, high=None, step=None, log=False, categories=(1, 2, 3, 4), tunable=True)]) – Root-polynomial degree (1–4). 2 is recommended.

  • target_illuminant (str) – Target whitepoint for the correction (e.g. 'D65').

  • median_filter_size (int) – Kernel size for per-ROI median filtering.

  • stddev_mag_threshold (float) – Column-stddev threshold for border detection during checker centering. Ignored when pad_checker is False.

  • pad_checker (bool) – When True, each ROI is centred and reflect-padded via center_and_pad_checker() to recover partially-clipped checker cards. Defaults to False because border-fill segmentation requires a fully-visible grid with intact gutters: reflect-padding fabricates extra mirrored swatch cells, which makes the connected-component count exceed the expected number of patches and trips the strict count gate. Only enable it for the clustering-era clipped-card workflow.

  • min_swatch_area_frac (Annotated[float, TuneSpec(low=0.1, high=0.6, step=None, log=False, categories=None, tunable=True)]) – During border-fill segmentation, connected components smaller than this fraction of the median component area are discarded as noise before the strict chip-count gate.

  • core_fraction (Annotated[float, TuneSpec(low=0.3, high=0.8, step=None, log=False, categories=None, tunable=True)]) – Fraction of centroid-to-boundary distance used to define the reliable core of each patch.

  • ridge_lambda (Annotated[float, TuneSpec(low=0.0001, high=0.1, step=None, log=True, categories=None, tunable=True)]) – Ridge-regression regularisation parameter for the root-polynomial fit.

  • outlier_sigma (Annotated[float, TuneSpec(low=1.5, high=4.0, step=None, log=False, categories=None, tunable=True)]) – Patches whose Delta-E 2000 exceeds mean + outlier_sigma * stddev are rejected as outliers.

  • rois (list[tuple[Annotated[slice, WithJsonSchema(json_schema={'type': 'object', 'description': 'A Python slice (start, stop, step) bounding a color-checker ROI along one image axis.'}, mode=None)], Annotated[slice, WithJsonSchema(json_schema={'type': 'object', 'description': 'A Python slice (start, stop, step) bounding a color-checker ROI along one image axis.'}, mode=None)]]] | None) – List of (row_slice, col_slice) tuples delimiting checker card regions in the source image. Stored for use by fit() and dashboard().

  • correction_matrix (Annotated[ndarray, BeforeValidator(func=~phenotypic.sdk_.typing_._coerce_to_ndarray, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~phenotypic.sdk_.typing_._ndarray_to_list, return_type=list, when_used=always), WithJsonSchema(json_schema={'type': 'array', 'items': {}}, mode=None)] | None)

  • diagnostics (dict[str, Any])

  • is_fitted (bool)

  • capture_metadata (CaptureMetadata | None)

correction_matrix

Fitted correction matrix once fit() or _fit_from_patch_colors() has been called; None on an unfitted profile.

Type:

NdArrayField | None

diagnostics

Per-patch and aggregate quality metrics.

Type:

dict[str, Any]

is_fitted

True after a successful fit.

Type:

bool

capture_metadata

Camera EXIF (make/model, lens, ISO, exposure, F-number, focal length) read from the calibration image during fit(). None for an unfitted profile or one fitted via _fit_from_patch_colors() (no source image). Serialises as a nested object under model_dump(); consumed by ColorCorrector to warn when a corrected image was shot on different optics. See CaptureMetadata.

Type:

CaptureMetadata | None

classmethod __get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler, /) JsonSchemaValue

Hook into generating the model’s JSON schema.

Parameters:
  • core_schema (CoreSchema) – A pydantic-core CoreSchema. You can ignore this argument and call the handler with a new CoreSchema, wrap this CoreSchema ({‘type’: ‘nullable’, ‘schema’: current_schema}), or just call the handler with the original schema.

  • handler (GetJsonSchemaHandler) – Call into Pydantic’s internal JSON schema generation. This will raise a pydantic.errors.PydanticInvalidForJsonSchema if JSON schema generation fails. Since this gets called by BaseModel.model_json_schema you can override the schema_generator argument to that function to change JSON schema generation globally for a type.

Returns:

A JSON schema, as a Python object.

Return type:

JsonSchemaValue

classmethod __pydantic_init_subclass__(**kwargs: Any) None

This is intended to behave just like __init_subclass__, but is called by ModelMetaclass only after basic class initialization is complete. In particular, attributes like model_fields will be present when this is called, but forward annotations are not guaranteed to be resolved yet, meaning that creating an instance of the class may fail.

This is necessary because __init_subclass__ will always be called by type.__new__, and it would require a prohibitively large refactor to the ModelMetaclass to ensure that type.__new__ was called in such a manner that the class would already be sufficiently initialized.

This will receive the same kwargs that would be passed to the standard __init_subclass__, namely, any kwargs passed to the class definition that aren’t used internally by Pydantic.

Parameters:

**kwargs (Any) – Any keyword arguments passed to the class definition that aren’t used internally by Pydantic.

Return type:

None

Note

You may want to override [__pydantic_on_complete__()][pydantic.main.BaseModel.__pydantic_on_complete__] instead, which is called once the class and its fields are fully initialized and ready for validation.

classmethod __pydantic_on_complete__() None

This is called once the class and its fields are fully initialized and ready to be used.

This typically happens when the class is created (just before [__pydantic_init_subclass__()][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass), except when forward annotations are used that could not immediately be resolved. In that case, it will be called later, when the model is rebuilt automatically or explicitly using [model_rebuild()][pydantic.main.BaseModel.model_rebuild].

Return type:

None

classmethod construct(_fields_set: set[str] | None = None, **values: Any) Self
Parameters:
Return type:

Self

classmethod from_json(json_data: str | Path | dict) ColorCheckerProfile[source]

Reconstruct a profile from JSON written by to_json().

Accepts a JSON string, a path to a JSON file, or a pre-parsed dict (same input handling as ImagePipeline.from_json()). Validation runs the _drop_legacy_fields() hook, so profiles saved before a field was removed still load.

Parameters:

json_data (str | Path | dict) – A JSON string, path to a JSON file, or a parsed dict.

Returns:

The reconstructed profile instance.

Return type:

ColorCheckerProfile

classmethod from_orm(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod model_construct(_fields_set: set[str] | None = None, **values: Any) Self

Creates a new instance of the Model class with validated data.

Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed.

!!! note

model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == ‘allow’, then all extra passed values are added to the model instance’s __dict__ and __pydantic_extra__ fields. If model_config.extra == ‘ignore’ (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == ‘forbid’ does not result in an error if extra values are passed, but they will be ignored.

Parameters:
  • _fields_set (set[str] | None) – A set of field names that were originally explicitly set during instantiation. If provided, this is directly used for the [model_fields_set][pydantic.BaseModel.model_fields_set] attribute. Otherwise, the field names from the values argument will be used.

  • values (Any) – Trusted or pre-validated data dictionary.

Returns:

A new instance of the Model class with validated data.

Return type:

Self

classmethod model_json_schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}', schema_generator: type[~pydantic.json_schema.GenerateJsonSchema] = <class 'pydantic.json_schema.GenerateJsonSchema'>, mode: ~typing.Literal['validation', 'serialization'] = 'validation', *, union_format: ~typing.Literal['any_of', 'primitive_type_array'] = 'any_of') dict[str, Any]

Generates a JSON schema for a model class.

Parameters:
  • by_alias (bool) – Whether to use attribute aliases or not.

  • ref_template (str) – The reference template.

  • union_format (Literal['any_of', 'primitive_type_array']) –

    The format to use when combining schemas from unions together. Can be one of:

    keyword to combine schemas (the default). - ‘primitive_type_array’: Use the [type](https://json-schema.org/understanding-json-schema/reference/type) keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive type (string, boolean, null, integer or number) or contains constraints/metadata, falls back to any_of.

  • schema_generator (type[GenerateJsonSchema]) – To override the logic used to generate the JSON schema, as a subclass of GenerateJsonSchema with your desired modifications

  • mode (Literal['validation', 'serialization']) – The mode in which to generate the schema.

Returns:

The JSON schema for the given model class.

Return type:

dict[str, Any]

classmethod model_parametrized_name(params: tuple[type[Any], ...]) str

Compute the class name for parametrizations of generic classes.

This method can be overridden to achieve a custom naming scheme for generic BaseModels.

Parameters:

params (tuple[type[Any], ...]) – Tuple of types of the class. Given a generic class Model with 2 type variables and a concrete model Model[str, int], the value (str, int) would be passed to params.

Returns:

String representing the new class where params are passed to cls as type variables.

Raises:

TypeError – Raised when trying to generate concrete names for non-generic models.

Return type:

str

classmethod model_rebuild(*, force: bool = False, raise_errors: bool = True, _parent_namespace_depth: int = 2, _types_namespace: MappingNamespace | None = None) bool | None

Try to rebuild the pydantic-core schema for the model.

This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.

Parameters:
  • force (bool) – Whether to force the rebuilding of the model schema, defaults to False.

  • raise_errors (bool) – Whether to raise errors, defaults to True.

  • _parent_namespace_depth (int) – The depth level of the parent namespace, defaults to 2.

  • _types_namespace (MappingNamespace | None) – The types namespace, defaults to None.

Returns:

Returns None if the schema is already “complete” and rebuilding was not required. If rebuilding _was_ required, returns True if rebuilding was successful, otherwise False.

Return type:

bool | None

classmethod model_validate(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, from_attributes: bool | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate a pydantic model instance.

Parameters:
  • obj (Any) – The object to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • from_attributes (bool | None) – Whether to extract data from object attributes.

  • context (Any | None) – Additional context to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Raises:

ValidationError – If the object could not be validated.

Returns:

The validated model instance.

Return type:

Self

classmethod model_validate_json(json_data: str | bytes | bytearray, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self
!!! abstract “Usage Documentation”

[JSON Parsing](../concepts/json.md#json-parsing)

Validate the given JSON data against the Pydantic model.

Parameters:
  • json_data (str | bytes | bytearray) – The JSON data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Raises:

ValidationError – If json_data is not a JSON string or the object could not be validated.

Return type:

Self

classmethod model_validate_strings(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate the given object with string data against the Pydantic model.

Parameters:
  • obj (Any) – The object containing string data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Return type:

Self

classmethod parse_file(path: str | Path, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • path (str | Path)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod parse_obj(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod parse_raw(b: str | bytes, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • b (str | bytes)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}') Dict[str, Any]
Parameters:
  • by_alias (bool)

  • ref_template (str)

Return type:

Dict[str, Any]

classmethod schema_json(*, by_alias: bool = True, ref_template: str = '#/$defs/{model}', **dumps_kwargs: Any) str
Parameters:
  • by_alias (bool)

  • ref_template (str)

  • dumps_kwargs (Any)

Return type:

str

classmethod update_forward_refs(**localns: Any) None
Parameters:

localns (Any)

Return type:

None

classmethod validate(value: Any) Self
Parameters:

value (Any)

Return type:

Self

__copy__() Self

Returns a shallow copy of the model.

Return type:

Self

__deepcopy__(memo: dict[int, Any] | None = None) Self

Returns a deep copy of the model.

Parameters:

memo (dict[int, Any] | None)

Return type:

Self

__init__(**data: Any) None

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:

data (Any)

Return type:

None

__iter__() Generator[tuple[str, Any], None, None]

So dict(model) works.

Return type:

Generator[tuple[str, Any], None, None]

__pretty__(fmt: Callable[[Any], Any], **kwargs: Any) Generator[Any]

Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects.

Parameters:
Return type:

Generator[Any]

__repr_name__() str

Name of the instance’s class, used in __repr__.

Return type:

str

__repr_recursion__(object: Any) str

Returns the string representation of a recursive object.

Parameters:

object (Any)

Return type:

str

__rich_repr__() RichReprResult

Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects.

Return type:

RichReprResult

copy(*, include: AbstractSetIntStr | MappingIntStrAny | None = None, exclude: AbstractSetIntStr | MappingIntStrAny | None = None, update: Dict[str, Any] | None = None, deep: bool = False) Self

Returns a copy of the model.

!!! warning “Deprecated”

This method is now deprecated; use model_copy instead.

If you need include or exclude, use:

`python {test="skip" lint="skip"} data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = {**data, **(update or {})} copied = self.model_validate(data) `

Parameters:
  • include (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to include in the copied model.

  • exclude (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to exclude in the copied model.

  • update (Dict[str, Any] | None) – Optional dictionary of field-value pairs to override field values in the copied model.

  • deep (bool) – If True, the values of fields that are Pydantic models will be deep-copied.

Returns:

A copy of the model with included, excluded and updated fields as specified.

Return type:

Self

dashboard(show: bool = True) Any[source]

Build the Plotly color-correction diagnostic report.

Constructs a ColorCorrectionReport from this fitted profile and returns its dash() rendering. The report declares no interactive controls, so dash() composes the per-section figures into a single plotly.graph_objects.Figure.

Uses the image and ROIs stored during fit(). When fitted via _fit_from_patch_colors() (no source image), the pipeline-step and segmentation figures are omitted.

Parameters:

show (bool) – When True and running inside a Jupyter notebook, display the figure inline before returning it. Set False in tests or for programmatic use.

Returns:

A plotly.graph_objects.Figure (always returned, even after an inline display).

Raises:

RuntimeError – If the profile has not been fitted.

Return type:

Any

dict(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False) Dict[str, Any]
Parameters:
Return type:

Dict[str, Any]

fit(image: Image) ColorCheckerProfile[source]

Fit the profile from checker-card ROIs stored at initialisation.

When rois was not provided at initialisation, the entire image is treated as a single ROI.

Parameters:

image (Image) – Source image containing visible checker cards.

Returns:

self for method chaining.

Return type:

ColorCheckerProfile

json(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Callable[[Any], Any] | None = PydanticUndefined, models_as_dict: bool = PydanticUndefined, **dumps_kwargs: Any) str
Parameters:
Return type:

str

model_copy(*, update: Mapping[str, Any] | None = None, deep: bool = False) Self
!!! abstract “Usage Documentation”

[model_copy](../concepts/models.md#model-copy)

Returns a copy of the model.

!!! note

The underlying instance’s [__dict__][object.__dict__] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).

Parameters:
  • update (Mapping[str, Any] | None) – Values to change/add in the new model. Note: the data is not validated before creating the new model. You should trust this data.

  • deep (bool) – Set to True to make a deep copy of the model.

Returns:

New model instance.

Return type:

Self

model_dump(*, mode: Literal['json', 'python'] | str = 'python', include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) dict[str, Any]
!!! abstract “Usage Documentation”

[model_dump](../concepts/serialization.md#python-mode)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Parameters:
  • mode (Literal['json', 'python'] | str) – The mode in which to_python should run. If mode is ‘json’, the output will only contain JSON serializable types. If mode is ‘python’, the output may contain non-JSON-serializable Python objects.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to include in the output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to exclude from the output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to use the field’s alias in the dictionary key if defined.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A dictionary representation of the model.

Return type:

dict[str, Any]

model_dump_json(*, indent: int | None = None, ensure_ascii: bool = False, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) str
!!! abstract “Usage Documentation”

[model_dump_json](../concepts/serialization.md#json-mode)

Generates a JSON representation of the model using Pydantic’s to_json method.

Parameters:
  • indent (int | None) – Indentation to use in the JSON output. If None is passed, the output will be compact.

  • ensure_ascii (bool) – If True, the output is guaranteed to have all incoming non-ASCII characters escaped. If False (the default), these characters will be output as-is.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to include in the JSON output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to exclude from the JSON output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to serialize using field aliases.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A JSON string representation of the model.

Return type:

str

model_post_init(context: Any, /) None

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

Return type:

None

to_json(filepath: str | Path | None = None) str | None[source]

Serialize this profile to JSON.

Serializes via model_dump_json(): the fitted correction_matrix is emitted as a nested list, capture_metadata as a nested object, and the transient rois / _image fields are excluded. Mirrors ImagePipeline.to_json().

Parameters:

filepath (str | Path | None) – Optional path to write the JSON to. When None, the JSON string is returned instead. Accepts a str or Path.

Returns:

The JSON string when filepath is None, otherwise None.

Return type:

str | None

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.correction import ColorCheckerProfile
>>> from phenotypic.sdk_ import CONFIG_SUFFIX_COLOR_CHECKER, ensure_typed_json_suffix
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "profile.json"
...     saved = ensure_typed_json_suffix(p, CONFIG_SUFFIX_COLOR_CHECKER)
...     ColorCheckerProfile(degree=3).to_json(p)
...     loaded = ColorCheckerProfile.from_json(saved)
>>> loaded.degree
3
capture_metadata: CaptureMetadata | None
checker_type: str
core_fraction: Annotated[float, TuneSpec(0.3, 0.8)]
correction_matrix: NdArrayField | None
degree: Annotated[int, TuneSpec(categories=1, 2, 3, 4)]
diagnostics: dict[str, Any]
is_fitted: bool
median_filter_size: int
min_swatch_area_frac: Annotated[float, TuneSpec(0.1, 0.6)]
model_computed_fields = {}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_extra: dict[str, Any] | None

Get extra fields set during validation.

Returns:

A dictionary of extra fields, or None if config.extra is not set to “allow”.

model_fields = {'capture_metadata': FieldInfo(annotation=Union[CaptureMetadata, NoneType], required=False, default=None), 'checker_type': FieldInfo(annotation=str, required=False, default='ColorChecker24 - After November 2014'), 'core_fraction': FieldInfo(annotation=float, required=False, default=0.5, metadata=[TuneSpec(low=0.3, high=0.8, step=None, log=False, categories=None, tunable=True)]), 'correction_matrix': FieldInfo(annotation=Union[Annotated[ndarray, BeforeValidator, PlainSerializer, WithJsonSchema], NoneType], required=False, default=None), 'degree': FieldInfo(annotation=int, required=False, default=2, metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=(1, 2, 3, 4), tunable=True)]), 'diagnostics': FieldInfo(annotation=dict[str, Any], required=False, default={}), 'is_fitted': FieldInfo(annotation=bool, required=False, default=False), 'median_filter_size': FieldInfo(annotation=int, required=False, default=10), 'min_swatch_area_frac': FieldInfo(annotation=float, required=False, default=0.3, metadata=[TuneSpec(low=0.1, high=0.6, step=None, log=False, categories=None, tunable=True)]), 'outlier_sigma': FieldInfo(annotation=float, required=False, default=2.0, metadata=[TuneSpec(low=1.5, high=4.0, step=None, log=False, categories=None, tunable=True)]), 'pad_checker': FieldInfo(annotation=bool, required=False, default=False), 'ridge_lambda': FieldInfo(annotation=float, required=False, default=0.001, metadata=[TuneSpec(low=0.0001, high=0.1, step=None, log=True, categories=None, tunable=True)]), 'rois': FieldInfo(annotation=Union[list[tuple[Annotated[slice, WithJsonSchema], Annotated[slice, WithJsonSchema]]], NoneType], required=False, default=None, exclude=True), 'stddev_mag_threshold': FieldInfo(annotation=float, required=False, default=15.0), 'target_illuminant': FieldInfo(annotation=str, required=False, default='D65')}
property model_fields_set: set[str]

Returns the set of fields that have been explicitly set on this model instance.

Returns:

A set of strings representing the fields that have been set,

i.e. that were not filled from defaults.

outlier_sigma: Annotated[float, TuneSpec(1.5, 4.0)]
pad_checker: bool
ridge_lambda: Annotated[float, TuneSpec(0.0001, 0.1, log=True)]
rois: list[tuple[_RoiSlice, _RoiSlice]] | None
stddev_mag_threshold: float
target_illuminant: str
class phenotypic.correction.ColorCorrector(*, profile: ColorCheckerProfile, output_illuminant: str = 'D65')[source]

Bases: ImageCorrector

Apply root-polynomial color correction using a fitted ColorCheckerProfile.

Decodes sRGB gamma to linear light, applies the root-polynomial expansion and the profile’s correction matrix, re-encodes to sRGB, and recomputes grayscale and detect_mat from the corrected RGB. The correction matrix is derived from a color checker captured under the same imaging conditions, so colony color becomes comparable across batches and acquisition setups.

For algorithm details, see Color Spaces for Phenotyping.

Best For:
  • Multi-batch studies imaged across sessions or scanners where colony color must be cross-batch comparable.

  • Plates with pigmented yeast or bacterial colonies where chromatic phenotype is the primary readout.

  • Publication workflows needing perceptually accurate color reproduction.

  • Removing color casts from DSLR or flatbed-scanner illuminants that shift colony hue relative to the agar background.

Consider Also:
  • FlattenIllumination when the artifact is a spatial brightness gradient rather than a chromatic cast.

  • ColorDenoise when high-ISO color noise obscures colony boundaries without a systematic color-cast problem.

  • BayesShrinkCorrector or VisuShrinkCorrector when the goal is noise reduction rather than color accuracy.

Parameters:
  • profile (ColorCheckerProfile) – A fitted ColorCheckerProfile supplying the root-polynomial correction matrix and expansion degree. An unfitted profile is rejected with a ValueError.

  • output_illuminant (str) – Target illuminant label used when reporting the corrected color space (informational only; does not alter the matrix computation). Default: "D65".

Returns:

rgb mapped through the correction matrix; gray and detect_mat recomputed from the corrected RGB. All three components are updated in a single pass.

Return type:

Image

Raises:
  • ValueError – If profile is not yet fitted.

  • UserWarning – If the image’s camera EXIF indicates a different camera body or lens than the one used when the profile was fitted.

See also

Tutorial 1: Your First Plate Image for an introduction to loading and correcting full-plate images. Color Spaces for Phenotyping for a discussion of root-polynomial color correction in phenotyping.

classmethod __get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler, /) JsonSchemaValue

Hook into generating the model’s JSON schema.

Parameters:
  • core_schema (CoreSchema) – A pydantic-core CoreSchema. You can ignore this argument and call the handler with a new CoreSchema, wrap this CoreSchema ({‘type’: ‘nullable’, ‘schema’: current_schema}), or just call the handler with the original schema.

  • handler (GetJsonSchemaHandler) – Call into Pydantic’s internal JSON schema generation. This will raise a pydantic.errors.PydanticInvalidForJsonSchema if JSON schema generation fails. Since this gets called by BaseModel.model_json_schema you can override the schema_generator argument to that function to change JSON schema generation globally for a type.

Returns:

A JSON schema, as a Python object.

Return type:

JsonSchemaValue

classmethod __pydantic_init_subclass__(**kwargs: Any) None

Populate field descriptions from the subclass docstring.

Runs once per concrete subclass after pydantic has built its model. Copies parameter descriptions parsed from the Google-style Args: docstring block onto each field’s description slot so they surface in model_json_schema() — the machine-readable contract used by downstream tooling (e.g. an MCP server).

Parameters:

**kwargs (Any) – Class-keyword arguments forwarded by pydantic.

Return type:

None

classmethod __pydantic_on_complete__() None

This is called once the class and its fields are fully initialized and ready to be used.

This typically happens when the class is created (just before [__pydantic_init_subclass__()][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass), except when forward annotations are used that could not immediately be resolved. In that case, it will be called later, when the model is rebuilt automatically or explicitly using [model_rebuild()][pydantic.main.BaseModel.model_rebuild].

Return type:

None

classmethod construct(_fields_set: set[str] | None = None, **values: Any) Self
Parameters:
Return type:

Self

classmethod from_json(json_data: str | Path | dict) BaseOperation

Reconstruct an operation from JSON written by to_json().

Accepts a JSON string, a path to a JSON file, or a pre-parsed envelope dict (same input handling as ImagePipeline.from_json()). Polymorphic: ImageOperation.from_json(path) returns whatever concrete operation the file holds. When called on a narrower subclass, the resolved class must be a subclass of it, else a TypeError is raised.

Parameters:

json_data (str | Path | dict) – A JSON string, path to a JSON file, or envelope dict.

Returns:

The reconstructed operation instance.

Raises:
  • AttributeError – If the recorded class cannot be resolved in the phenotypic namespace.

  • TypeError – If called on a concrete subclass and the file holds a class that is not a subclass of it.

Return type:

BaseOperation

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.abc_ import ImageOperation
>>> from phenotypic.detect import OtsuDetector
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     OtsuDetector().to_json(p)
...     loaded = ImageOperation.from_json(p)  # polymorphic
>>> type(loaded).__name__
'OtsuDetector'
classmethod from_orm(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod model_construct(_fields_set: set[str] | None = None, **values: Any) Self

Creates a new instance of the Model class with validated data.

Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed.

!!! note

model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == ‘allow’, then all extra passed values are added to the model instance’s __dict__ and __pydantic_extra__ fields. If model_config.extra == ‘ignore’ (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == ‘forbid’ does not result in an error if extra values are passed, but they will be ignored.

Parameters:
  • _fields_set (set[str] | None) – A set of field names that were originally explicitly set during instantiation. If provided, this is directly used for the [model_fields_set][pydantic.BaseModel.model_fields_set] attribute. Otherwise, the field names from the values argument will be used.

  • values (Any) – Trusted or pre-validated data dictionary.

Returns:

A new instance of the Model class with validated data.

Return type:

Self

classmethod model_json_schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}', schema_generator: type[~pydantic.json_schema.GenerateJsonSchema] = <class 'pydantic.json_schema.GenerateJsonSchema'>, mode: ~typing.Literal['validation', 'serialization'] = 'validation', *, union_format: ~typing.Literal['any_of', 'primitive_type_array'] = 'any_of') dict[str, Any]

Generates a JSON schema for a model class.

Parameters:
  • by_alias (bool) – Whether to use attribute aliases or not.

  • ref_template (str) – The reference template.

  • union_format (Literal['any_of', 'primitive_type_array']) –

    The format to use when combining schemas from unions together. Can be one of:

    keyword to combine schemas (the default). - ‘primitive_type_array’: Use the [type](https://json-schema.org/understanding-json-schema/reference/type) keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive type (string, boolean, null, integer or number) or contains constraints/metadata, falls back to any_of.

  • schema_generator (type[GenerateJsonSchema]) – To override the logic used to generate the JSON schema, as a subclass of GenerateJsonSchema with your desired modifications

  • mode (Literal['validation', 'serialization']) – The mode in which to generate the schema.

Returns:

The JSON schema for the given model class.

Return type:

dict[str, Any]

classmethod model_parametrized_name(params: tuple[type[Any], ...]) str

Compute the class name for parametrizations of generic classes.

This method can be overridden to achieve a custom naming scheme for generic BaseModels.

Parameters:

params (tuple[type[Any], ...]) – Tuple of types of the class. Given a generic class Model with 2 type variables and a concrete model Model[str, int], the value (str, int) would be passed to params.

Returns:

String representing the new class where params are passed to cls as type variables.

Raises:

TypeError – Raised when trying to generate concrete names for non-generic models.

Return type:

str

classmethod model_rebuild(*, force: bool = False, raise_errors: bool = True, _parent_namespace_depth: int = 2, _types_namespace: MappingNamespace | None = None) bool | None

Try to rebuild the pydantic-core schema for the model.

This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.

Parameters:
  • force (bool) – Whether to force the rebuilding of the model schema, defaults to False.

  • raise_errors (bool) – Whether to raise errors, defaults to True.

  • _parent_namespace_depth (int) – The depth level of the parent namespace, defaults to 2.

  • _types_namespace (MappingNamespace | None) – The types namespace, defaults to None.

Returns:

Returns None if the schema is already “complete” and rebuilding was not required. If rebuilding _was_ required, returns True if rebuilding was successful, otherwise False.

Return type:

bool | None

classmethod model_validate(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, from_attributes: bool | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate a pydantic model instance.

Parameters:
  • obj (Any) – The object to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • from_attributes (bool | None) – Whether to extract data from object attributes.

  • context (Any | None) – Additional context to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Raises:

ValidationError – If the object could not be validated.

Returns:

The validated model instance.

Return type:

Self

classmethod model_validate_json(json_data: str | bytes | bytearray, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self
!!! abstract “Usage Documentation”

[JSON Parsing](../concepts/json.md#json-parsing)

Validate the given JSON data against the Pydantic model.

Parameters:
  • json_data (str | bytes | bytearray) – The JSON data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Raises:

ValidationError – If json_data is not a JSON string or the object could not be validated.

Return type:

Self

classmethod model_validate_strings(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate the given object with string data against the Pydantic model.

Parameters:
  • obj (Any) – The object containing string data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Return type:

Self

classmethod parse_file(path: str | Path, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • path (str | Path)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod parse_obj(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod parse_raw(b: str | bytes, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • b (str | bytes)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}') Dict[str, Any]
Parameters:
  • by_alias (bool)

  • ref_template (str)

Return type:

Dict[str, Any]

classmethod schema_json(*, by_alias: bool = True, ref_template: str = '#/$defs/{model}', **dumps_kwargs: Any) str
Parameters:
  • by_alias (bool)

  • ref_template (str)

  • dumps_kwargs (Any)

Return type:

str

classmethod update_forward_refs(**localns: Any) None
Parameters:

localns (Any)

Return type:

None

classmethod validate(value: Any) Self
Parameters:

value (Any)

Return type:

Self

__copy__() Self

Returns a shallow copy of the model.

Return type:

Self

__deepcopy__(memo: dict[int, Any] | None = None) Self

Returns a deep copy of the model.

Parameters:

memo (dict[int, Any] | None)

Return type:

Self

__del__()

Automatically stop tracemalloc when the object is deleted.

__init__(**data: Any) None

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:

data (Any)

Return type:

None

__iter__() Generator[tuple[str, Any], None, None]

So dict(model) works.

Return type:

Generator[tuple[str, Any], None, None]

__pretty__(fmt: Callable[[Any], Any], **kwargs: Any) Generator[Any]

Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects.

Parameters:
Return type:

Generator[Any]

__repr_name__() str

Name of the instance’s class, used in __repr__.

Return type:

str

__repr_recursion__(object: Any) str

Returns the string representation of a recursive object.

Parameters:

object (Any)

Return type:

str

__rich_repr__() RichReprResult

Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects.

Return type:

RichReprResult

apply(image: Image, inplace: bool = False) Image[source]

Apply the correction, first checking capture-metadata compatibility.

The compatibility check runs against the input image (before the defensive copy apply makes for inplace=False), because Image.copy() does not carry imported EXIF forward.

Parameters:
  • image (Image) – Image to correct.

  • inplace (bool) – When False (default) operate on a copy.

Returns:

The corrected image.

Return type:

Image

copy(*, include: AbstractSetIntStr | MappingIntStrAny | None = None, exclude: AbstractSetIntStr | MappingIntStrAny | None = None, update: Dict[str, Any] | None = None, deep: bool = False) Self

Returns a copy of the model.

!!! warning “Deprecated”

This method is now deprecated; use model_copy instead.

If you need include or exclude, use:

`python {test="skip" lint="skip"} data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = {**data, **(update or {})} copied = self.model_validate(data) `

Parameters:
  • include (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to include in the copied model.

  • exclude (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to exclude in the copied model.

  • update (Dict[str, Any] | None) – Optional dictionary of field-value pairs to override field values in the copied model.

  • deep (bool) – If True, the values of fields that are Pydantic models will be deep-copied.

Returns:

A copy of the model with included, excluded and updated fields as specified.

Return type:

Self

dashboard(show: bool = True) Any[source]

Build the Plotly color-correction diagnostic report.

Delegates to the underlying profile’s ColorCheckerProfile.dashboard().

Parameters:

show (bool) – When True and running inside a Jupyter notebook, display the figure inline before returning it.

Returns:

A plotly.graph_objects.Figure (always returned, even after an inline display).

Return type:

Any

dict(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False) Dict[str, Any]
Parameters:
Return type:

Dict[str, Any]

json(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Callable[[Any], Any] | None = PydanticUndefined, models_as_dict: bool = PydanticUndefined, **dumps_kwargs: Any) str
Parameters:
Return type:

str

model_copy(*, update: Mapping[str, Any] | None = None, deep: bool = False) Self
!!! abstract “Usage Documentation”

[model_copy](../concepts/models.md#model-copy)

Returns a copy of the model.

!!! note

The underlying instance’s [__dict__][object.__dict__] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).

Parameters:
  • update (Mapping[str, Any] | None) – Values to change/add in the new model. Note: the data is not validated before creating the new model. You should trust this data.

  • deep (bool) – Set to True to make a deep copy of the model.

Returns:

New model instance.

Return type:

Self

model_dump(*, mode: Literal['json', 'python'] | str = 'python', include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) dict[str, Any]
!!! abstract “Usage Documentation”

[model_dump](../concepts/serialization.md#python-mode)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Parameters:
  • mode (Literal['json', 'python'] | str) – The mode in which to_python should run. If mode is ‘json’, the output will only contain JSON serializable types. If mode is ‘python’, the output may contain non-JSON-serializable Python objects.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to include in the output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to exclude from the output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to use the field’s alias in the dictionary key if defined.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A dictionary representation of the model.

Return type:

dict[str, Any]

model_dump_json(*, indent: int | None = None, ensure_ascii: bool = False, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) str
!!! abstract “Usage Documentation”

[model_dump_json](../concepts/serialization.md#json-mode)

Generates a JSON representation of the model using Pydantic’s to_json method.

Parameters:
  • indent (int | None) – Indentation to use in the JSON output. If None is passed, the output will be compact.

  • ensure_ascii (bool) – If True, the output is guaranteed to have all incoming non-ASCII characters escaped. If False (the default), these characters will be output as-is.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to include in the JSON output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to exclude from the JSON output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to serialize using field aliases.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A JSON string representation of the model.

Return type:

str

model_post_init(_ColorCorrector__context: Any) None[source]

Materialise the float64 correction matrix after construction.

Extends BaseOperation.model_post_init() (which sets up the logger): caches a float64 copy of the fitted profile’s correction matrix so _operate() does not rebuild it per call.

Parameters:
  • __context – Pydantic post-init context (unused).

  • _ColorCorrector__context (Any)

Return type:

None

to_json(filepath: str | Path | None = None) str | None

Serialize this operation to JSON.

Captures the operation as a {"class", "params"} envelope: params is model_dump(mode="json") (every declared field, including nested operations and raw arrays; PrivateAttr state such as loggers and timing is excluded automatically), and class records the concrete class name so from_json() can rebuild the right subclass. This mirrors ImagePipeline.to_json().

Parameters:

filepath (str | Path | None) – Optional path to write the JSON to. When None, the JSON string is returned instead. Accepts a str or Path.

Returns:

The JSON string when filepath is None, otherwise None.

Return type:

str | None

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.detect import OtsuDetector
>>> from phenotypic.sdk_ import CONFIG_SUFFIX_OPERATION, ensure_typed_json_suffix
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     saved = ensure_typed_json_suffix(p, CONFIG_SUFFIX_OPERATION)
...     OtsuDetector(ignore_zeros=True).to_json(p)
...     loaded = OtsuDetector.from_json(saved)
>>> loaded.ignore_zeros
True
widget(image: Image | None = None, show: bool = False) Widget

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.

property correction_matrix: list

The root-polynomial correction matrix as a nested list.

property degree: int

Polynomial expansion degree, matching the profile.

model_computed_fields = {}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_extra: dict[str, Any] | None

Get extra fields set during validation.

Returns:

A dictionary of extra fields, or None if config.extra is not set to “allow”.

model_fields = {'output_illuminant': FieldInfo(annotation=str, required=False, default='D65', description='Target illuminant label used when reporting the corrected color space (informational only; does not alter the matrix computation). Default: ``"D65"``.'), 'profile': FieldInfo(annotation=ColorCheckerProfile, required=True, description='A fitted :class:`ColorCheckerProfile` supplying the root-polynomial correction matrix and expansion degree. An unfitted profile is rejected with a ``ValueError``.')}
property model_fields_set: set[str]

Returns the set of fields that have been explicitly set on this model instance.

Returns:

A set of strings representing the fields that have been set,

i.e. that were not filled from defaults.

output_illuminant: str
profile: ColorCheckerProfile
class phenotypic.correction.ColorDenoise(*, sigma_psd: Annotated[float, TuneSpec(low=0.01, high=0.15, step=None, log=True, categories=None, tunable=True)] = 0.02, block_size: Annotated[int, TuneSpec(low=None, high=None, step=None, log=False, categories=4, 8, 16, tunable=True)] = 8, clip: bool = True, use_gat: bool = False, gat_gain: Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = 1.0, gat_mu: Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = 0.0, gat_read_sigma: Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = 0.0, gat_scale_factor: Annotated[float | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None)[source]

Bases: ImageCorrector

Denoise an RGB plate image using color block-matching 3D filtering (CBM3D).

Apply the color extension of BM3D jointly across the three sRGB channels in the linear-light domain, decorrelating color into a luminance-chrominance space and computing patch grouping once on the luminance channel for reuse across the chrominance channels. Writing the cleaned RGB through the accessor cascade automatically rebuilds gray and detect_mat from the corrected data.

For algorithm details, see What Enhancement Actually Does.

Best For:
  • RGB plate scans where colony color composition is subsequently measured and chrominance fidelity at colony boundaries must be preserved.

  • Structured camera or scanner sensor noise that should be suppressed while preserving colony color fidelity.

  • Publication-quality plate figures requiring visually clean, color-accurate RGB images.

  • Low-light or high-ISO DSLR plate captures with Poisson-Gaussian mixed noise, using use_gat=True.

Consider Also:
  • BayesShrinkCorrector for faster wavelet-based denoising of all components when CBM3D runtime is prohibitive.

  • DenoiseBlockMatch for GAT-stabilized BM3D on the grayscale channel when only intensity measurements are needed.

  • NonLocalMeansDenoiser when a simpler, lower-cost denoiser for the detection matrix is sufficient.

Parameters:
  • sigma_psd (Annotated[float, TuneSpec(low=0.01, high=0.15, step=None, log=True, categories=None, tunable=True)]) – Gaussian noise standard deviation in the linear-light [0, 1] domain after sRGB decoding. Typical range: 0.01–0.05 for moderate flatbed-scanner noise; 0.05–0.15 for heavy noise from high-ISO or low-light captures. Too low leaves structured noise intact; too high erases fine colony texture and inter-colony gap detail. Ignored when use_gat=True; the stabilized-domain value 1.0 is used internally. Default: 0.02.

  • block_size (Annotated[int, TuneSpec(low=None, high=None, step=None, log=False, categories=(4, 8, 16), tunable=True)]) – Side length in pixels of the 2D patches used for block-matching. Sets both the hard-thresholding and Wiener stage block sizes. Larger values capture more spatial context and improve denoising of uniform agar backgrounds but increase computation quadratically. Typical range: 4–16. Default: 8.

  • clip (bool) – Clamp the sRGB-re-encoded result to [0, 1] before rescaling to the original integer dtype, preventing rare BM3D overshoot near high-contrast colony edges from causing integer wraparound. Default: True.

  • parameters (# GAT)

  • use_gat (bool) – Wrap the per-channel CBM3D call in the Generalized Anscombe Transform, converting Poisson-Gaussian mixed noise to approximately unit-variance Gaussian so BM3D operates optimally. Enable for fluorescence plate readers or high-ISO DSLR images where shot noise dominates. Default: False.

  • gat_gain (Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Camera gain in electrons per ADU for the GAT noise model. Scales the Poisson variance component. Typical range: 0.5–10 e-/ADU depending on sensor; obtain from the manufacturer datasheet or a mean-variance calibration. Default: 1.0.

  • gat_mu (Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Read-noise mean (dark-current baseline offset) in count units consistent with gat_scale_factor. Set to 0.0 when the image has been bias-subtracted, which covers most plate-scanner workflows. Default: 0.0.

  • gat_read_sigma (Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Read-noise standard deviation in count units consistent with gat_scale_factor. Zero assumes pure Poisson noise; supplying the sensor read-noise spec (a few to a few tens of counts for typical scientific CCDs) improves stabilization accuracy at low signal levels. Default: 0.0.

  • gat_scale_factor (Annotated[float | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Multiplier converting normalized [0, 1] linear-light data to photon counts before the forward GAT. None auto-detects from the image bit depth (8-bit: 255, 16-bit: 65535). Override for non-standard bit depths such as 12-bit sensors stored in a 16-bit container (4095). Default: None.

Returns:

Input image with rgb replaced by the CBM3D-denoised result. gray and detect_mat are automatically recomputed from the cleaned RGB via the accessor cascade.

Return type:

Image

Raises:

ValueError – If the image has no RGB data, if sigma_psd is negative, block_size is not positive, gat_gain is not positive, gat_read_sigma is negative, or gat_scale_factor is not positive.

References

[1] K. Dabov, A. Foi, V. Katkovnik, and K. Egiazarian, “Image denoising by sparse 3-D transform-domain collaborative filtering,” IEEE Trans. Image Process., vol. 16, no. 8, pp. 2080–2095, Aug. 2007.

[2] K. Dabov, A. Foi, V. Katkovnik, and K. Egiazarian, “Color image denoising via sparse 3D collaborative filtering with grouping constraint in luminance-chrominance space,” in Proc. IEEE Int. Conf. Image Process. (ICIP), 2007, pp. I-313–I-316.

[3] M. Mäkitalo and A. Foi, “Optimal inversion of the generalized Anscombe transformation for Poisson-Gaussian noise,” IEEE Trans. Image Process., vol. 22, no. 1, pp. 91–103, Jan. 2013.

See also

Tutorial 3: Enhancing Before Detection for a visual walkthrough of denoising pipelines on plate images. Image Quality: Noise, Contrast, and Structure for background on noise models and denoiser selection.

classmethod __get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler, /) JsonSchemaValue

Hook into generating the model’s JSON schema.

Parameters:
  • core_schema (CoreSchema) – A pydantic-core CoreSchema. You can ignore this argument and call the handler with a new CoreSchema, wrap this CoreSchema ({‘type’: ‘nullable’, ‘schema’: current_schema}), or just call the handler with the original schema.

  • handler (GetJsonSchemaHandler) – Call into Pydantic’s internal JSON schema generation. This will raise a pydantic.errors.PydanticInvalidForJsonSchema if JSON schema generation fails. Since this gets called by BaseModel.model_json_schema you can override the schema_generator argument to that function to change JSON schema generation globally for a type.

Returns:

A JSON schema, as a Python object.

Return type:

JsonSchemaValue

classmethod __pydantic_init_subclass__(**kwargs: Any) None

Populate field descriptions from the subclass docstring.

Runs once per concrete subclass after pydantic has built its model. Copies parameter descriptions parsed from the Google-style Args: docstring block onto each field’s description slot so they surface in model_json_schema() — the machine-readable contract used by downstream tooling (e.g. an MCP server).

Parameters:

**kwargs (Any) – Class-keyword arguments forwarded by pydantic.

Return type:

None

classmethod __pydantic_on_complete__() None

This is called once the class and its fields are fully initialized and ready to be used.

This typically happens when the class is created (just before [__pydantic_init_subclass__()][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass), except when forward annotations are used that could not immediately be resolved. In that case, it will be called later, when the model is rebuilt automatically or explicitly using [model_rebuild()][pydantic.main.BaseModel.model_rebuild].

Return type:

None

classmethod construct(_fields_set: set[str] | None = None, **values: Any) Self
Parameters:
Return type:

Self

classmethod from_json(json_data: str | Path | dict) BaseOperation

Reconstruct an operation from JSON written by to_json().

Accepts a JSON string, a path to a JSON file, or a pre-parsed envelope dict (same input handling as ImagePipeline.from_json()). Polymorphic: ImageOperation.from_json(path) returns whatever concrete operation the file holds. When called on a narrower subclass, the resolved class must be a subclass of it, else a TypeError is raised.

Parameters:

json_data (str | Path | dict) – A JSON string, path to a JSON file, or envelope dict.

Returns:

The reconstructed operation instance.

Raises:
  • AttributeError – If the recorded class cannot be resolved in the phenotypic namespace.

  • TypeError – If called on a concrete subclass and the file holds a class that is not a subclass of it.

Return type:

BaseOperation

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.abc_ import ImageOperation
>>> from phenotypic.detect import OtsuDetector
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     OtsuDetector().to_json(p)
...     loaded = ImageOperation.from_json(p)  # polymorphic
>>> type(loaded).__name__
'OtsuDetector'
classmethod from_orm(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod model_construct(_fields_set: set[str] | None = None, **values: Any) Self

Creates a new instance of the Model class with validated data.

Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed.

!!! note

model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == ‘allow’, then all extra passed values are added to the model instance’s __dict__ and __pydantic_extra__ fields. If model_config.extra == ‘ignore’ (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == ‘forbid’ does not result in an error if extra values are passed, but they will be ignored.

Parameters:
  • _fields_set (set[str] | None) – A set of field names that were originally explicitly set during instantiation. If provided, this is directly used for the [model_fields_set][pydantic.BaseModel.model_fields_set] attribute. Otherwise, the field names from the values argument will be used.

  • values (Any) – Trusted or pre-validated data dictionary.

Returns:

A new instance of the Model class with validated data.

Return type:

Self

classmethod model_json_schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}', schema_generator: type[~pydantic.json_schema.GenerateJsonSchema] = <class 'pydantic.json_schema.GenerateJsonSchema'>, mode: ~typing.Literal['validation', 'serialization'] = 'validation', *, union_format: ~typing.Literal['any_of', 'primitive_type_array'] = 'any_of') dict[str, Any]

Generates a JSON schema for a model class.

Parameters:
  • by_alias (bool) – Whether to use attribute aliases or not.

  • ref_template (str) – The reference template.

  • union_format (Literal['any_of', 'primitive_type_array']) –

    The format to use when combining schemas from unions together. Can be one of:

    keyword to combine schemas (the default). - ‘primitive_type_array’: Use the [type](https://json-schema.org/understanding-json-schema/reference/type) keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive type (string, boolean, null, integer or number) or contains constraints/metadata, falls back to any_of.

  • schema_generator (type[GenerateJsonSchema]) – To override the logic used to generate the JSON schema, as a subclass of GenerateJsonSchema with your desired modifications

  • mode (Literal['validation', 'serialization']) – The mode in which to generate the schema.

Returns:

The JSON schema for the given model class.

Return type:

dict[str, Any]

classmethod model_parametrized_name(params: tuple[type[Any], ...]) str

Compute the class name for parametrizations of generic classes.

This method can be overridden to achieve a custom naming scheme for generic BaseModels.

Parameters:

params (tuple[type[Any], ...]) – Tuple of types of the class. Given a generic class Model with 2 type variables and a concrete model Model[str, int], the value (str, int) would be passed to params.

Returns:

String representing the new class where params are passed to cls as type variables.

Raises:

TypeError – Raised when trying to generate concrete names for non-generic models.

Return type:

str

classmethod model_rebuild(*, force: bool = False, raise_errors: bool = True, _parent_namespace_depth: int = 2, _types_namespace: MappingNamespace | None = None) bool | None

Try to rebuild the pydantic-core schema for the model.

This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.

Parameters:
  • force (bool) – Whether to force the rebuilding of the model schema, defaults to False.

  • raise_errors (bool) – Whether to raise errors, defaults to True.

  • _parent_namespace_depth (int) – The depth level of the parent namespace, defaults to 2.

  • _types_namespace (MappingNamespace | None) – The types namespace, defaults to None.

Returns:

Returns None if the schema is already “complete” and rebuilding was not required. If rebuilding _was_ required, returns True if rebuilding was successful, otherwise False.

Return type:

bool | None

classmethod model_validate(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, from_attributes: bool | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate a pydantic model instance.

Parameters:
  • obj (Any) – The object to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • from_attributes (bool | None) – Whether to extract data from object attributes.

  • context (Any | None) – Additional context to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Raises:

ValidationError – If the object could not be validated.

Returns:

The validated model instance.

Return type:

Self

classmethod model_validate_json(json_data: str | bytes | bytearray, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self
!!! abstract “Usage Documentation”

[JSON Parsing](../concepts/json.md#json-parsing)

Validate the given JSON data against the Pydantic model.

Parameters:
  • json_data (str | bytes | bytearray) – The JSON data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Raises:

ValidationError – If json_data is not a JSON string or the object could not be validated.

Return type:

Self

classmethod model_validate_strings(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate the given object with string data against the Pydantic model.

Parameters:
  • obj (Any) – The object containing string data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Return type:

Self

classmethod parse_file(path: str | Path, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • path (str | Path)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod parse_obj(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod parse_raw(b: str | bytes, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • b (str | bytes)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}') Dict[str, Any]
Parameters:
  • by_alias (bool)

  • ref_template (str)

Return type:

Dict[str, Any]

classmethod schema_json(*, by_alias: bool = True, ref_template: str = '#/$defs/{model}', **dumps_kwargs: Any) str
Parameters:
  • by_alias (bool)

  • ref_template (str)

  • dumps_kwargs (Any)

Return type:

str

classmethod update_forward_refs(**localns: Any) None
Parameters:

localns (Any)

Return type:

None

classmethod validate(value: Any) Self
Parameters:

value (Any)

Return type:

Self

__copy__() Self

Returns a shallow copy of the model.

Return type:

Self

__deepcopy__(memo: dict[int, Any] | None = None) Self

Returns a deep copy of the model.

Parameters:

memo (dict[int, Any] | None)

Return type:

Self

__del__()

Automatically stop tracemalloc when the object is deleted.

__init__(**data: Any) None

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:

data (Any)

Return type:

None

__iter__() Generator[tuple[str, Any], None, None]

So dict(model) works.

Return type:

Generator[tuple[str, Any], None, None]

__pretty__(fmt: Callable[[Any], Any], **kwargs: Any) Generator[Any]

Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects.

Parameters:
Return type:

Generator[Any]

__repr_name__() str

Name of the instance’s class, used in __repr__.

Return type:

str

__repr_recursion__(object: Any) str

Returns the string representation of a recursive object.

Parameters:

object (Any)

Return type:

str

__rich_repr__() RichReprResult

Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects.

Return type:

RichReprResult

apply(image: Image, inplace: bool = False) Image

Applies the operation to an image, either in-place or on a copy.

Parameters:
  • image (Image) – The arr image to apply the operation on.

  • inplace (bool) – If True, modifies the image in place; otherwise, operates on a copy of the image.

Returns:

The modified image after applying the operation.

Return type:

Image

copy(*, include: AbstractSetIntStr | MappingIntStrAny | None = None, exclude: AbstractSetIntStr | MappingIntStrAny | None = None, update: Dict[str, Any] | None = None, deep: bool = False) Self

Returns a copy of the model.

!!! warning “Deprecated”

This method is now deprecated; use model_copy instead.

If you need include or exclude, use:

`python {test="skip" lint="skip"} data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = {**data, **(update or {})} copied = self.model_validate(data) `

Parameters:
  • include (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to include in the copied model.

  • exclude (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to exclude in the copied model.

  • update (Dict[str, Any] | None) – Optional dictionary of field-value pairs to override field values in the copied model.

  • deep (bool) – If True, the values of fields that are Pydantic models will be deep-copied.

Returns:

A copy of the model with included, excluded and updated fields as specified.

Return type:

Self

dict(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False) Dict[str, Any]
Parameters:
Return type:

Dict[str, Any]

json(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Callable[[Any], Any] | None = PydanticUndefined, models_as_dict: bool = PydanticUndefined, **dumps_kwargs: Any) str
Parameters:
Return type:

str

model_copy(*, update: Mapping[str, Any] | None = None, deep: bool = False) Self
!!! abstract “Usage Documentation”

[model_copy](../concepts/models.md#model-copy)

Returns a copy of the model.

!!! note

The underlying instance’s [__dict__][object.__dict__] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).

Parameters:
  • update (Mapping[str, Any] | None) – Values to change/add in the new model. Note: the data is not validated before creating the new model. You should trust this data.

  • deep (bool) – Set to True to make a deep copy of the model.

Returns:

New model instance.

Return type:

Self

model_dump(*, mode: Literal['json', 'python'] | str = 'python', include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) dict[str, Any]
!!! abstract “Usage Documentation”

[model_dump](../concepts/serialization.md#python-mode)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Parameters:
  • mode (Literal['json', 'python'] | str) – The mode in which to_python should run. If mode is ‘json’, the output will only contain JSON serializable types. If mode is ‘python’, the output may contain non-JSON-serializable Python objects.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to include in the output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to exclude from the output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to use the field’s alias in the dictionary key if defined.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A dictionary representation of the model.

Return type:

dict[str, Any]

model_dump_json(*, indent: int | None = None, ensure_ascii: bool = False, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) str
!!! abstract “Usage Documentation”

[model_dump_json](../concepts/serialization.md#json-mode)

Generates a JSON representation of the model using Pydantic’s to_json method.

Parameters:
  • indent (int | None) – Indentation to use in the JSON output. If None is passed, the output will be compact.

  • ensure_ascii (bool) – If True, the output is guaranteed to have all incoming non-ASCII characters escaped. If False (the default), these characters will be output as-is.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to include in the JSON output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to exclude from the JSON output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to serialize using field aliases.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A JSON string representation of the model.

Return type:

str

model_post_init(_BaseOperation__context: Any) None

Initialize logging and memory tracking after model construction.

Replaces the legacy __init__ body: creates the per-class logger and, when that logger is enabled for INFO level or higher, starts tracemalloc so per-operation memory usage can be logged.

Parameters:
  • __context – Pydantic post-init context (unused).

  • _BaseOperation__context (Any)

Return type:

None

to_json(filepath: str | Path | None = None) str | None

Serialize this operation to JSON.

Captures the operation as a {"class", "params"} envelope: params is model_dump(mode="json") (every declared field, including nested operations and raw arrays; PrivateAttr state such as loggers and timing is excluded automatically), and class records the concrete class name so from_json() can rebuild the right subclass. This mirrors ImagePipeline.to_json().

Parameters:

filepath (str | Path | None) – Optional path to write the JSON to. When None, the JSON string is returned instead. Accepts a str or Path.

Returns:

The JSON string when filepath is None, otherwise None.

Return type:

str | None

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.detect import OtsuDetector
>>> from phenotypic.sdk_ import CONFIG_SUFFIX_OPERATION, ensure_typed_json_suffix
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     saved = ensure_typed_json_suffix(p, CONFIG_SUFFIX_OPERATION)
...     OtsuDetector(ignore_zeros=True).to_json(p)
...     loaded = OtsuDetector.from_json(saved)
>>> loaded.ignore_zeros
True
widget(image: Image | None = None, show: bool = False) Widget

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.

block_size: Annotated[int, TuneSpec(categories=4, 8, 16)]
clip: bool
gat_gain: Annotated[float, TuneSpec(tunable=False)]
gat_mu: Annotated[float, TuneSpec(tunable=False)]
gat_read_sigma: Annotated[float, TuneSpec(tunable=False)]
gat_scale_factor: Annotated[float | None, TuneSpec(tunable=False)]
model_computed_fields = {}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_extra: dict[str, Any] | None

Get extra fields set during validation.

Returns:

A dictionary of extra fields, or None if config.extra is not set to “allow”.

model_fields = {'block_size': FieldInfo(annotation=int, required=False, default=8, description='Side length in pixels of the 2D patches used for block-matching. Sets both the hard-thresholding and Wiener stage block sizes. Larger values capture more spatial context and improve denoising of uniform agar backgrounds but increase computation quadratically. Typical range: 4--16. Default: ``8``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=(4, 8, 16), tunable=True)]), 'clip': FieldInfo(annotation=bool, required=False, default=True, description='Clamp the sRGB-re-encoded result to [0, 1] before rescaling to the original integer dtype, preventing rare BM3D overshoot near high-contrast colony edges from causing integer wraparound.'), 'gat_gain': FieldInfo(annotation=float, required=False, default=1.0, description='Camera gain in electrons per ADU for the GAT noise model. Scales the Poisson variance component. Typical range: 0.5--10 e-/ADU depending on sensor; obtain from the manufacturer datasheet or a mean-variance calibration. Default: ``1.0``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'gat_mu': FieldInfo(annotation=float, required=False, default=0.0, description='Read-noise mean (dark-current baseline offset) in count units consistent with ``gat_scale_factor``. Set to 0.0 when the image has been bias-subtracted, which covers most plate-scanner workflows. Default: ``0.0``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'gat_read_sigma': FieldInfo(annotation=float, required=False, default=0.0, description='Read-noise standard deviation in count units consistent with ``gat_scale_factor``. Zero assumes pure Poisson noise; supplying the sensor read-noise spec (a few to a few tens of counts for typical scientific CCDs) improves stabilization accuracy at low signal levels. Default: ``0.0``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'gat_scale_factor': FieldInfo(annotation=Union[float, NoneType], required=False, default=None, description='Multiplier converting normalized [0, 1] linear-light data to photon counts before the forward GAT. ``None`` auto-detects from the image bit depth (8-bit: 255, 16-bit: 65535). Override for non-standard bit depths such as 12-bit sensors stored in a 16-bit container (4095). Default: ``None``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'sigma_psd': FieldInfo(annotation=float, required=False, default=0.02, description='Gaussian noise standard deviation in the linear-light [0, 1] domain after sRGB decoding. Typical range: 0.01--0.05 for moderate flatbed-scanner noise; 0.05--0.15 for heavy noise from high-ISO or low-light captures. Too low leaves structured noise intact; too high erases fine colony texture and inter-colony gap detail. Ignored when ``use_gat=True``; the stabilized-domain value 1.0 is used internally. Default: ``0.02``.', metadata=[TuneSpec(low=0.01, high=0.15, step=None, log=True, categories=None, tunable=True)]), 'use_gat': FieldInfo(annotation=bool, required=False, default=False, description='Wrap the per-channel CBM3D call in the Generalized Anscombe Transform, converting Poisson-Gaussian mixed noise to approximately unit-variance Gaussian so BM3D operates optimally. Enable for fluorescence plate readers or high-ISO DSLR images where shot noise dominates. Default: ``False``.')}
property model_fields_set: set[str]

Returns the set of fields that have been explicitly set on this model instance.

Returns:

A set of strings representing the fields that have been set,

i.e. that were not filled from defaults.

sigma_psd: Annotated[float, TuneSpec(0.01, 0.15, log=True)]
use_gat: bool
class phenotypic.correction.DenoiseBlockMatch(*, block_size: Annotated[int, TuneSpec(low=None, high=None, step=None, log=False, categories=4, 8, 16, tunable=True)] = 8, stage_arg: Literal['all_stages', 'hard_thresholding'] = 'all_stages', gain: Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = 1.0, mu: Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = 0.0, sigma: Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = 0.0, scale_factor: Annotated[float | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None)[source]

Bases: ImageCorrector

Denoise the grayscale channel using GAT-stabilized BM3D collaborative filtering.

Combine the Generalized Anscombe Transform (GAT) with BM3D block-matching and 3D filtering in a single corrector step. The forward GAT converts Poisson-Gaussian mixed noise to approximately unit-variance Gaussian so BM3D operates with a theoretically correct noise model; the exact unbiased inverse GAT then restores the original intensity scale. Writing back through the gray accessor automatically resets detect_mat, so downstream reads reflect the denoised result.

For algorithm details, see What Enhancement Actually Does.

Best For:
  • Low-light or high-ISO plate images where photon shot noise (Poisson component) is comparable to or larger than read noise.

  • Improving intensity measurement accuracy before colony size or opacity quantification on CCD/sCMOS imaged plates.

  • Fluorescence plate reader images with signal-dependent noise where a purely Gaussian denoiser would leave structured residuals.

Consider Also:
  • BayesShrinkCorrector when all image components including RGB need simultaneous wavelet denoising.

  • EnhanceBlockMatch for BM3D applied only to the detection matrix without altering the grayscale channel.

  • VisuShrinkCorrector for a faster wavelet alternative when Poisson noise modelling is not required.

Parameters:
  • block_size (Annotated[int, TuneSpec(low=None, high=None, step=None, log=False, categories=(4, 8, 16), tunable=True)]) – Side length in pixels of the 2D patches used in BM3D block-matching. Larger values capture more spatial context and denoise smooth agar backgrounds more effectively; smaller values preserve fine colony texture and thin hyphal edges. Typical range: 4–16. Default: 8.

  • stage_arg (Literal['all_stages', 'hard_thresholding']) – BM3D processing stages. 'all_stages' runs the two-stage pipeline (hard-thresholding basic estimate followed by Wiener collaborative filtering) for best denoising quality. 'hard_thresholding' skips the Wiener stage for roughly 40–50% faster execution at the cost of more residual noise. Default: 'all_stages'.

  • gain (Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Camera gain in electrons per ADU for the GAT noise model. Scales the Poisson variance component in the forward transform. Typical range: 0.5–10 e-/ADU depending on sensor; obtain from the sensor datasheet or a mean-variance calibration. Must be positive. Default: 1.0.

  • mu (Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Read-noise mean (dark-current baseline offset) in count units consistent with scale_factor. Set to 0.0 when the image has been bias-subtracted, which covers most plate-scanner workflows. Default: 0.0.

  • sigma (Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Read-noise standard deviation in count units consistent with scale_factor. 0.0 assumes pure Poisson noise, appropriate for most plate scanners under normal exposure. Supplying the sensor read-noise spec (a few to a few tens of counts for typical scientific CCDs) improves stabilization in low-signal regions. Must be non-negative. Default: 0.0.

  • scale_factor (Annotated[float | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Multiplier converting normalized [0, 1] grayscale data to photon counts before the forward GAT. None auto-detects from image bit depth (8-bit: 255, 16-bit: 65535). Override for non-standard bit depths such as 12-bit sensors stored in a 16-bit container (4095). Must be positive when supplied. Default: None.

Returns:

Input image with the grayscale channel replaced by the GAT-stabilized BM3D-denoised result. rgb is unchanged; detect_mat is automatically reset via the gray accessor cascade.

Return type:

Image

Raises:

ValueError – If gain is not positive, sigma is negative, scale_factor is not positive when supplied, or stage_arg is not a recognized value.

References

[1] K. Dabov, A. Foi, V. Katkovnik, and K. Egiazarian, “Image denoising by sparse 3-D transform-domain collaborative filtering,” IEEE Trans. Image Process., vol. 16, no. 8, pp. 2080–2095, Aug. 2007.

[2] M. Mäkitalo and A. Foi, “Optimal inversion of the generalized Anscombe transformation for Poisson-Gaussian noise,” IEEE Trans. Image Process., vol. 22, no. 1, pp. 91–103, Jan. 2013.

See also

How To: Denoise Low-Light Images for a walkthrough of denoising low-light plate images. Image Quality: Noise, Contrast, and Structure for background on Poisson-Gaussian noise models and denoiser selection.

classmethod __get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler, /) JsonSchemaValue

Hook into generating the model’s JSON schema.

Parameters:
  • core_schema (CoreSchema) – A pydantic-core CoreSchema. You can ignore this argument and call the handler with a new CoreSchema, wrap this CoreSchema ({‘type’: ‘nullable’, ‘schema’: current_schema}), or just call the handler with the original schema.

  • handler (GetJsonSchemaHandler) – Call into Pydantic’s internal JSON schema generation. This will raise a pydantic.errors.PydanticInvalidForJsonSchema if JSON schema generation fails. Since this gets called by BaseModel.model_json_schema you can override the schema_generator argument to that function to change JSON schema generation globally for a type.

Returns:

A JSON schema, as a Python object.

Return type:

JsonSchemaValue

classmethod __pydantic_init_subclass__(**kwargs: Any) None

Populate field descriptions from the subclass docstring.

Runs once per concrete subclass after pydantic has built its model. Copies parameter descriptions parsed from the Google-style Args: docstring block onto each field’s description slot so they surface in model_json_schema() — the machine-readable contract used by downstream tooling (e.g. an MCP server).

Parameters:

**kwargs (Any) – Class-keyword arguments forwarded by pydantic.

Return type:

None

classmethod __pydantic_on_complete__() None

This is called once the class and its fields are fully initialized and ready to be used.

This typically happens when the class is created (just before [__pydantic_init_subclass__()][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass), except when forward annotations are used that could not immediately be resolved. In that case, it will be called later, when the model is rebuilt automatically or explicitly using [model_rebuild()][pydantic.main.BaseModel.model_rebuild].

Return type:

None

classmethod construct(_fields_set: set[str] | None = None, **values: Any) Self
Parameters:
Return type:

Self

classmethod from_json(json_data: str | Path | dict) BaseOperation

Reconstruct an operation from JSON written by to_json().

Accepts a JSON string, a path to a JSON file, or a pre-parsed envelope dict (same input handling as ImagePipeline.from_json()). Polymorphic: ImageOperation.from_json(path) returns whatever concrete operation the file holds. When called on a narrower subclass, the resolved class must be a subclass of it, else a TypeError is raised.

Parameters:

json_data (str | Path | dict) – A JSON string, path to a JSON file, or envelope dict.

Returns:

The reconstructed operation instance.

Raises:
  • AttributeError – If the recorded class cannot be resolved in the phenotypic namespace.

  • TypeError – If called on a concrete subclass and the file holds a class that is not a subclass of it.

Return type:

BaseOperation

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.abc_ import ImageOperation
>>> from phenotypic.detect import OtsuDetector
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     OtsuDetector().to_json(p)
...     loaded = ImageOperation.from_json(p)  # polymorphic
>>> type(loaded).__name__
'OtsuDetector'
classmethod from_orm(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod model_construct(_fields_set: set[str] | None = None, **values: Any) Self

Creates a new instance of the Model class with validated data.

Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed.

!!! note

model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == ‘allow’, then all extra passed values are added to the model instance’s __dict__ and __pydantic_extra__ fields. If model_config.extra == ‘ignore’ (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == ‘forbid’ does not result in an error if extra values are passed, but they will be ignored.

Parameters:
  • _fields_set (set[str] | None) – A set of field names that were originally explicitly set during instantiation. If provided, this is directly used for the [model_fields_set][pydantic.BaseModel.model_fields_set] attribute. Otherwise, the field names from the values argument will be used.

  • values (Any) – Trusted or pre-validated data dictionary.

Returns:

A new instance of the Model class with validated data.

Return type:

Self

classmethod model_json_schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}', schema_generator: type[~pydantic.json_schema.GenerateJsonSchema] = <class 'pydantic.json_schema.GenerateJsonSchema'>, mode: ~typing.Literal['validation', 'serialization'] = 'validation', *, union_format: ~typing.Literal['any_of', 'primitive_type_array'] = 'any_of') dict[str, Any]

Generates a JSON schema for a model class.

Parameters:
  • by_alias (bool) – Whether to use attribute aliases or not.

  • ref_template (str) – The reference template.

  • union_format (Literal['any_of', 'primitive_type_array']) –

    The format to use when combining schemas from unions together. Can be one of:

    keyword to combine schemas (the default). - ‘primitive_type_array’: Use the [type](https://json-schema.org/understanding-json-schema/reference/type) keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive type (string, boolean, null, integer or number) or contains constraints/metadata, falls back to any_of.

  • schema_generator (type[GenerateJsonSchema]) – To override the logic used to generate the JSON schema, as a subclass of GenerateJsonSchema with your desired modifications

  • mode (Literal['validation', 'serialization']) – The mode in which to generate the schema.

Returns:

The JSON schema for the given model class.

Return type:

dict[str, Any]

classmethod model_parametrized_name(params: tuple[type[Any], ...]) str

Compute the class name for parametrizations of generic classes.

This method can be overridden to achieve a custom naming scheme for generic BaseModels.

Parameters:

params (tuple[type[Any], ...]) – Tuple of types of the class. Given a generic class Model with 2 type variables and a concrete model Model[str, int], the value (str, int) would be passed to params.

Returns:

String representing the new class where params are passed to cls as type variables.

Raises:

TypeError – Raised when trying to generate concrete names for non-generic models.

Return type:

str

classmethod model_rebuild(*, force: bool = False, raise_errors: bool = True, _parent_namespace_depth: int = 2, _types_namespace: MappingNamespace | None = None) bool | None

Try to rebuild the pydantic-core schema for the model.

This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.

Parameters:
  • force (bool) – Whether to force the rebuilding of the model schema, defaults to False.

  • raise_errors (bool) – Whether to raise errors, defaults to True.

  • _parent_namespace_depth (int) – The depth level of the parent namespace, defaults to 2.

  • _types_namespace (MappingNamespace | None) – The types namespace, defaults to None.

Returns:

Returns None if the schema is already “complete” and rebuilding was not required. If rebuilding _was_ required, returns True if rebuilding was successful, otherwise False.

Return type:

bool | None

classmethod model_validate(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, from_attributes: bool | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate a pydantic model instance.

Parameters:
  • obj (Any) – The object to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • from_attributes (bool | None) – Whether to extract data from object attributes.

  • context (Any | None) – Additional context to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Raises:

ValidationError – If the object could not be validated.

Returns:

The validated model instance.

Return type:

Self

classmethod model_validate_json(json_data: str | bytes | bytearray, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self
!!! abstract “Usage Documentation”

[JSON Parsing](../concepts/json.md#json-parsing)

Validate the given JSON data against the Pydantic model.

Parameters:
  • json_data (str | bytes | bytearray) – The JSON data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Raises:

ValidationError – If json_data is not a JSON string or the object could not be validated.

Return type:

Self

classmethod model_validate_strings(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate the given object with string data against the Pydantic model.

Parameters:
  • obj (Any) – The object containing string data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Return type:

Self

classmethod parse_file(path: str | Path, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • path (str | Path)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod parse_obj(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod parse_raw(b: str | bytes, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • b (str | bytes)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}') Dict[str, Any]
Parameters:
  • by_alias (bool)

  • ref_template (str)

Return type:

Dict[str, Any]

classmethod schema_json(*, by_alias: bool = True, ref_template: str = '#/$defs/{model}', **dumps_kwargs: Any) str
Parameters:
  • by_alias (bool)

  • ref_template (str)

  • dumps_kwargs (Any)

Return type:

str

classmethod update_forward_refs(**localns: Any) None
Parameters:

localns (Any)

Return type:

None

classmethod validate(value: Any) Self
Parameters:

value (Any)

Return type:

Self

__copy__() Self

Returns a shallow copy of the model.

Return type:

Self

__deepcopy__(memo: dict[int, Any] | None = None) Self

Returns a deep copy of the model.

Parameters:

memo (dict[int, Any] | None)

Return type:

Self

__del__()

Automatically stop tracemalloc when the object is deleted.

__init__(**data: Any) None

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:

data (Any)

Return type:

None

__iter__() Generator[tuple[str, Any], None, None]

So dict(model) works.

Return type:

Generator[tuple[str, Any], None, None]

__pretty__(fmt: Callable[[Any], Any], **kwargs: Any) Generator[Any]

Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects.

Parameters:
Return type:

Generator[Any]

__repr_name__() str

Name of the instance’s class, used in __repr__.

Return type:

str

__repr_recursion__(object: Any) str

Returns the string representation of a recursive object.

Parameters:

object (Any)

Return type:

str

__rich_repr__() RichReprResult

Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects.

Return type:

RichReprResult

apply(image: Image, inplace: bool = False) Image

Applies the operation to an image, either in-place or on a copy.

Parameters:
  • image (Image) – The arr image to apply the operation on.

  • inplace (bool) – If True, modifies the image in place; otherwise, operates on a copy of the image.

Returns:

The modified image after applying the operation.

Return type:

Image

copy(*, include: AbstractSetIntStr | MappingIntStrAny | None = None, exclude: AbstractSetIntStr | MappingIntStrAny | None = None, update: Dict[str, Any] | None = None, deep: bool = False) Self

Returns a copy of the model.

!!! warning “Deprecated”

This method is now deprecated; use model_copy instead.

If you need include or exclude, use:

`python {test="skip" lint="skip"} data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = {**data, **(update or {})} copied = self.model_validate(data) `

Parameters:
  • include (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to include in the copied model.

  • exclude (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to exclude in the copied model.

  • update (Dict[str, Any] | None) – Optional dictionary of field-value pairs to override field values in the copied model.

  • deep (bool) – If True, the values of fields that are Pydantic models will be deep-copied.

Returns:

A copy of the model with included, excluded and updated fields as specified.

Return type:

Self

dict(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False) Dict[str, Any]
Parameters:
Return type:

Dict[str, Any]

json(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Callable[[Any], Any] | None = PydanticUndefined, models_as_dict: bool = PydanticUndefined, **dumps_kwargs: Any) str
Parameters:
Return type:

str

model_copy(*, update: Mapping[str, Any] | None = None, deep: bool = False) Self
!!! abstract “Usage Documentation”

[model_copy](../concepts/models.md#model-copy)

Returns a copy of the model.

!!! note

The underlying instance’s [__dict__][object.__dict__] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).

Parameters:
  • update (Mapping[str, Any] | None) – Values to change/add in the new model. Note: the data is not validated before creating the new model. You should trust this data.

  • deep (bool) – Set to True to make a deep copy of the model.

Returns:

New model instance.

Return type:

Self

model_dump(*, mode: Literal['json', 'python'] | str = 'python', include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) dict[str, Any]
!!! abstract “Usage Documentation”

[model_dump](../concepts/serialization.md#python-mode)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Parameters:
  • mode (Literal['json', 'python'] | str) – The mode in which to_python should run. If mode is ‘json’, the output will only contain JSON serializable types. If mode is ‘python’, the output may contain non-JSON-serializable Python objects.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to include in the output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to exclude from the output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to use the field’s alias in the dictionary key if defined.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A dictionary representation of the model.

Return type:

dict[str, Any]

model_dump_json(*, indent: int | None = None, ensure_ascii: bool = False, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) str
!!! abstract “Usage Documentation”

[model_dump_json](../concepts/serialization.md#json-mode)

Generates a JSON representation of the model using Pydantic’s to_json method.

Parameters:
  • indent (int | None) – Indentation to use in the JSON output. If None is passed, the output will be compact.

  • ensure_ascii (bool) – If True, the output is guaranteed to have all incoming non-ASCII characters escaped. If False (the default), these characters will be output as-is.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to include in the JSON output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to exclude from the JSON output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to serialize using field aliases.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A JSON string representation of the model.

Return type:

str

model_post_init(_BaseOperation__context: Any) None

Initialize logging and memory tracking after model construction.

Replaces the legacy __init__ body: creates the per-class logger and, when that logger is enabled for INFO level or higher, starts tracemalloc so per-operation memory usage can be logged.

Parameters:
  • __context – Pydantic post-init context (unused).

  • _BaseOperation__context (Any)

Return type:

None

to_json(filepath: str | Path | None = None) str | None

Serialize this operation to JSON.

Captures the operation as a {"class", "params"} envelope: params is model_dump(mode="json") (every declared field, including nested operations and raw arrays; PrivateAttr state such as loggers and timing is excluded automatically), and class records the concrete class name so from_json() can rebuild the right subclass. This mirrors ImagePipeline.to_json().

Parameters:

filepath (str | Path | None) – Optional path to write the JSON to. When None, the JSON string is returned instead. Accepts a str or Path.

Returns:

The JSON string when filepath is None, otherwise None.

Return type:

str | None

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.detect import OtsuDetector
>>> from phenotypic.sdk_ import CONFIG_SUFFIX_OPERATION, ensure_typed_json_suffix
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     saved = ensure_typed_json_suffix(p, CONFIG_SUFFIX_OPERATION)
...     OtsuDetector(ignore_zeros=True).to_json(p)
...     loaded = OtsuDetector.from_json(saved)
>>> loaded.ignore_zeros
True
widget(image: Image | None = None, show: bool = False) Widget

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.

block_size: Annotated[int, TuneSpec(categories=4, 8, 16)]
gain: Annotated[float, TuneSpec(tunable=False)]
model_computed_fields = {}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_extra: dict[str, Any] | None

Get extra fields set during validation.

Returns:

A dictionary of extra fields, or None if config.extra is not set to “allow”.

model_fields = {'block_size': FieldInfo(annotation=int, required=False, default=8, description='Side length in pixels of the 2D patches used in BM3D block-matching. Larger values capture more spatial context and denoise smooth agar backgrounds more effectively; smaller values preserve fine colony texture and thin hyphal edges. Typical range: 4--16. Default: ``8``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=(4, 8, 16), tunable=True)]), 'gain': FieldInfo(annotation=float, required=False, default=1.0, description='Camera gain in electrons per ADU for the GAT noise model. Scales the Poisson variance component in the forward transform. Typical range: 0.5--10 e-/ADU depending on sensor; obtain from the sensor datasheet or a mean-variance calibration. Must be positive.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'mu': FieldInfo(annotation=float, required=False, default=0.0, description='Read-noise mean (dark-current baseline offset) in count units consistent with ``scale_factor``. Set to 0.0 when the image has been bias-subtracted, which covers most plate-scanner workflows.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'scale_factor': FieldInfo(annotation=Union[float, NoneType], required=False, default=None, description='Multiplier converting normalized [0, 1] grayscale data to photon counts before the forward GAT. ``None`` auto-detects from image bit depth (8-bit: 255, 16-bit: 65535). Override for non-standard bit depths such as 12-bit sensors stored in a 16-bit container (4095). Must be positive when supplied. Default: ``None``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'sigma': FieldInfo(annotation=float, required=False, default=0.0, description='Read-noise standard deviation in count units consistent with ``scale_factor``. ``0.0`` assumes pure Poisson noise, appropriate for most plate scanners under normal exposure. Supplying the sensor read-noise spec (a few to a few tens of counts for typical scientific CCDs) improves stabilization in low-signal regions. Must be non-negative. Default: ``0.0``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'stage_arg': FieldInfo(annotation=Literal['all_stages', 'hard_thresholding'], required=False, default='all_stages', description="BM3D processing stages. ``'all_stages'`` runs the two-stage pipeline (hard-thresholding basic estimate followed by Wiener collaborative filtering) for best denoising quality. ``'hard_thresholding'`` skips the Wiener stage for roughly 40--50% faster execution at the cost of more residual noise.")}
property model_fields_set: set[str]

Returns the set of fields that have been explicitly set on this model instance.

Returns:

A set of strings representing the fields that have been set,

i.e. that were not filled from defaults.

mu: Annotated[float, TuneSpec(tunable=False)]
scale_factor: Annotated[float | None, TuneSpec(tunable=False)]
sigma: Annotated[float, TuneSpec(tunable=False)]
stage_arg: Literal['all_stages', 'hard_thresholding']
class phenotypic.correction.GridAligner(*, axis: Annotated[int, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = 0, mode: str = 'edge')[source]

Bases: GridCorrector

Correct grid rotation by fitting colony centroids to the target row or column axis.

Estimates the optimal rotation angle by regressing detected colony centroid positions along the chosen axis, then rotates every image component together and recalculates grid positions on the corrected image. Re-running detection after alignment is recommended, since pixel coordinates shift once the image is rotated.

For algorithm details, see Grid vs Non-Grid Detection.

Best For:
  • Arrayed plates scanned at a slight angle where rows or columns are not axis-aligned.

  • High-throughput setups with inconsistent plate orientation between scans.

  • Pre-processing before grid-based measurement to keep row and column assignment accurate.

Consider Also:
  • ImagePadder for adding safety margins before rotation so corner colonies are not clipped by the rotation fill.

  • ImageCropper to remove the fill border introduced after alignment.

  • RefineBySineFit when the grid periodicity itself needs correction rather than a global rotation.

Parameters:
  • axis (Annotated[int, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Alignment axis. 0 regresses centroid positions within each row to correct horizontal skew; 1 regresses within each column to correct vertical skew. Default: 0.

  • mode (str) – Edge-fill strategy passed to the image rotation. 'edge' replicates the nearest border pixel (avoids dark corners); 'constant' fills with zeros. Default: 'edge'.

Returns:

Input image rotated so colony centroids align with the chosen axis. All components (RGB, gray, detect_mat, objmask, objmap) are transformed together.

Return type:

GridImage

Raises:

ValueError – If axis is not 0 or 1.

See also

How To: Correct Grid Rotation for a visual walkthrough of grid alignment on real plate images.

classmethod __get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler, /) JsonSchemaValue

Hook into generating the model’s JSON schema.

Parameters:
  • core_schema (CoreSchema) – A pydantic-core CoreSchema. You can ignore this argument and call the handler with a new CoreSchema, wrap this CoreSchema ({‘type’: ‘nullable’, ‘schema’: current_schema}), or just call the handler with the original schema.

  • handler (GetJsonSchemaHandler) – Call into Pydantic’s internal JSON schema generation. This will raise a pydantic.errors.PydanticInvalidForJsonSchema if JSON schema generation fails. Since this gets called by BaseModel.model_json_schema you can override the schema_generator argument to that function to change JSON schema generation globally for a type.

Returns:

A JSON schema, as a Python object.

Return type:

JsonSchemaValue

classmethod __pydantic_init_subclass__(**kwargs: Any) None

Populate field descriptions from the subclass docstring.

Runs once per concrete subclass after pydantic has built its model. Copies parameter descriptions parsed from the Google-style Args: docstring block onto each field’s description slot so they surface in model_json_schema() — the machine-readable contract used by downstream tooling (e.g. an MCP server).

Parameters:

**kwargs (Any) – Class-keyword arguments forwarded by pydantic.

Return type:

None

classmethod __pydantic_on_complete__() None

This is called once the class and its fields are fully initialized and ready to be used.

This typically happens when the class is created (just before [__pydantic_init_subclass__()][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass), except when forward annotations are used that could not immediately be resolved. In that case, it will be called later, when the model is rebuilt automatically or explicitly using [model_rebuild()][pydantic.main.BaseModel.model_rebuild].

Return type:

None

classmethod construct(_fields_set: set[str] | None = None, **values: Any) Self
Parameters:
Return type:

Self

classmethod from_json(json_data: str | Path | dict) BaseOperation

Reconstruct an operation from JSON written by to_json().

Accepts a JSON string, a path to a JSON file, or a pre-parsed envelope dict (same input handling as ImagePipeline.from_json()). Polymorphic: ImageOperation.from_json(path) returns whatever concrete operation the file holds. When called on a narrower subclass, the resolved class must be a subclass of it, else a TypeError is raised.

Parameters:

json_data (str | Path | dict) – A JSON string, path to a JSON file, or envelope dict.

Returns:

The reconstructed operation instance.

Raises:
  • AttributeError – If the recorded class cannot be resolved in the phenotypic namespace.

  • TypeError – If called on a concrete subclass and the file holds a class that is not a subclass of it.

Return type:

BaseOperation

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.abc_ import ImageOperation
>>> from phenotypic.detect import OtsuDetector
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     OtsuDetector().to_json(p)
...     loaded = ImageOperation.from_json(p)  # polymorphic
>>> type(loaded).__name__
'OtsuDetector'
classmethod from_orm(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod model_construct(_fields_set: set[str] | None = None, **values: Any) Self

Creates a new instance of the Model class with validated data.

Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed.

!!! note

model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == ‘allow’, then all extra passed values are added to the model instance’s __dict__ and __pydantic_extra__ fields. If model_config.extra == ‘ignore’ (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == ‘forbid’ does not result in an error if extra values are passed, but they will be ignored.

Parameters:
  • _fields_set (set[str] | None) – A set of field names that were originally explicitly set during instantiation. If provided, this is directly used for the [model_fields_set][pydantic.BaseModel.model_fields_set] attribute. Otherwise, the field names from the values argument will be used.

  • values (Any) – Trusted or pre-validated data dictionary.

Returns:

A new instance of the Model class with validated data.

Return type:

Self

classmethod model_json_schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}', schema_generator: type[~pydantic.json_schema.GenerateJsonSchema] = <class 'pydantic.json_schema.GenerateJsonSchema'>, mode: ~typing.Literal['validation', 'serialization'] = 'validation', *, union_format: ~typing.Literal['any_of', 'primitive_type_array'] = 'any_of') dict[str, Any]

Generates a JSON schema for a model class.

Parameters:
  • by_alias (bool) – Whether to use attribute aliases or not.

  • ref_template (str) – The reference template.

  • union_format (Literal['any_of', 'primitive_type_array']) –

    The format to use when combining schemas from unions together. Can be one of:

    keyword to combine schemas (the default). - ‘primitive_type_array’: Use the [type](https://json-schema.org/understanding-json-schema/reference/type) keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive type (string, boolean, null, integer or number) or contains constraints/metadata, falls back to any_of.

  • schema_generator (type[GenerateJsonSchema]) – To override the logic used to generate the JSON schema, as a subclass of GenerateJsonSchema with your desired modifications

  • mode (Literal['validation', 'serialization']) – The mode in which to generate the schema.

Returns:

The JSON schema for the given model class.

Return type:

dict[str, Any]

classmethod model_parametrized_name(params: tuple[type[Any], ...]) str

Compute the class name for parametrizations of generic classes.

This method can be overridden to achieve a custom naming scheme for generic BaseModels.

Parameters:

params (tuple[type[Any], ...]) – Tuple of types of the class. Given a generic class Model with 2 type variables and a concrete model Model[str, int], the value (str, int) would be passed to params.

Returns:

String representing the new class where params are passed to cls as type variables.

Raises:

TypeError – Raised when trying to generate concrete names for non-generic models.

Return type:

str

classmethod model_rebuild(*, force: bool = False, raise_errors: bool = True, _parent_namespace_depth: int = 2, _types_namespace: MappingNamespace | None = None) bool | None

Try to rebuild the pydantic-core schema for the model.

This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.

Parameters:
  • force (bool) – Whether to force the rebuilding of the model schema, defaults to False.

  • raise_errors (bool) – Whether to raise errors, defaults to True.

  • _parent_namespace_depth (int) – The depth level of the parent namespace, defaults to 2.

  • _types_namespace (MappingNamespace | None) – The types namespace, defaults to None.

Returns:

Returns None if the schema is already “complete” and rebuilding was not required. If rebuilding _was_ required, returns True if rebuilding was successful, otherwise False.

Return type:

bool | None

classmethod model_validate(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, from_attributes: bool | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate a pydantic model instance.

Parameters:
  • obj (Any) – The object to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • from_attributes (bool | None) – Whether to extract data from object attributes.

  • context (Any | None) – Additional context to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Raises:

ValidationError – If the object could not be validated.

Returns:

The validated model instance.

Return type:

Self

classmethod model_validate_json(json_data: str | bytes | bytearray, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self
!!! abstract “Usage Documentation”

[JSON Parsing](../concepts/json.md#json-parsing)

Validate the given JSON data against the Pydantic model.

Parameters:
  • json_data (str | bytes | bytearray) – The JSON data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Raises:

ValidationError – If json_data is not a JSON string or the object could not be validated.

Return type:

Self

classmethod model_validate_strings(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate the given object with string data against the Pydantic model.

Parameters:
  • obj (Any) – The object containing string data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Return type:

Self

classmethod parse_file(path: str | Path, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • path (str | Path)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod parse_obj(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod parse_raw(b: str | bytes, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • b (str | bytes)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}') Dict[str, Any]
Parameters:
  • by_alias (bool)

  • ref_template (str)

Return type:

Dict[str, Any]

classmethod schema_json(*, by_alias: bool = True, ref_template: str = '#/$defs/{model}', **dumps_kwargs: Any) str
Parameters:
  • by_alias (bool)

  • ref_template (str)

  • dumps_kwargs (Any)

Return type:

str

classmethod update_forward_refs(**localns: Any) None
Parameters:

localns (Any)

Return type:

None

classmethod validate(value: Any) Self
Parameters:

value (Any)

Return type:

Self

__copy__() Self

Returns a shallow copy of the model.

Return type:

Self

__deepcopy__(memo: dict[int, Any] | None = None) Self

Returns a deep copy of the model.

Parameters:

memo (dict[int, Any] | None)

Return type:

Self

__del__()

Automatically stop tracemalloc when the object is deleted.

__init__(**data: Any) None

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:

data (Any)

Return type:

None

__iter__() Generator[tuple[str, Any], None, None]

So dict(model) works.

Return type:

Generator[tuple[str, Any], None, None]

__pretty__(fmt: Callable[[Any], Any], **kwargs: Any) Generator[Any]

Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects.

Parameters:
Return type:

Generator[Any]

__repr_name__() str

Name of the instance’s class, used in __repr__.

Return type:

str

__repr_recursion__(object: Any) str

Returns the string representation of a recursive object.

Parameters:

object (Any)

Return type:

str

__rich_repr__() RichReprResult

Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects.

Return type:

RichReprResult

apply(image: GridImage, inplace=False) GridImage

Calculates the optimal rotation angle and applies it to a grid image for alignment along the specified axis.

The method performs alignment of a GridImage object along either nrows or columns based on the specified axis. It calculates the linear regression slope and intercept for the axis, determines geometric properties of the grid vertices, and computes rotation angles needed to align the image. The optimal angle is found by minimizing the error across all computed angles, and the image is rotated accordingly.

Raises:

ValueError – If the axis is not 0 (row-wise) or 1 (column-wise).

Parameters:

image (ImageGridHandler) – The arr grid image object to be aligned.

Returns:

The rotated grid image object after alignment.

Return type:

ImageGridHandler

copy(*, include: AbstractSetIntStr | MappingIntStrAny | None = None, exclude: AbstractSetIntStr | MappingIntStrAny | None = None, update: Dict[str, Any] | None = None, deep: bool = False) Self

Returns a copy of the model.

!!! warning “Deprecated”

This method is now deprecated; use model_copy instead.

If you need include or exclude, use:

`python {test="skip" lint="skip"} data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = {**data, **(update or {})} copied = self.model_validate(data) `

Parameters:
  • include (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to include in the copied model.

  • exclude (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to exclude in the copied model.

  • update (Dict[str, Any] | None) – Optional dictionary of field-value pairs to override field values in the copied model.

  • deep (bool) – If True, the values of fields that are Pydantic models will be deep-copied.

Returns:

A copy of the model with included, excluded and updated fields as specified.

Return type:

Self

dict(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False) Dict[str, Any]
Parameters:
Return type:

Dict[str, Any]

json(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Callable[[Any], Any] | None = PydanticUndefined, models_as_dict: bool = PydanticUndefined, **dumps_kwargs: Any) str
Parameters:
Return type:

str

model_copy(*, update: Mapping[str, Any] | None = None, deep: bool = False) Self
!!! abstract “Usage Documentation”

[model_copy](../concepts/models.md#model-copy)

Returns a copy of the model.

!!! note

The underlying instance’s [__dict__][object.__dict__] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).

Parameters:
  • update (Mapping[str, Any] | None) – Values to change/add in the new model. Note: the data is not validated before creating the new model. You should trust this data.

  • deep (bool) – Set to True to make a deep copy of the model.

Returns:

New model instance.

Return type:

Self

model_dump(*, mode: Literal['json', 'python'] | str = 'python', include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) dict[str, Any]
!!! abstract “Usage Documentation”

[model_dump](../concepts/serialization.md#python-mode)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Parameters:
  • mode (Literal['json', 'python'] | str) – The mode in which to_python should run. If mode is ‘json’, the output will only contain JSON serializable types. If mode is ‘python’, the output may contain non-JSON-serializable Python objects.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to include in the output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to exclude from the output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to use the field’s alias in the dictionary key if defined.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A dictionary representation of the model.

Return type:

dict[str, Any]

model_dump_json(*, indent: int | None = None, ensure_ascii: bool = False, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) str
!!! abstract “Usage Documentation”

[model_dump_json](../concepts/serialization.md#json-mode)

Generates a JSON representation of the model using Pydantic’s to_json method.

Parameters:
  • indent (int | None) – Indentation to use in the JSON output. If None is passed, the output will be compact.

  • ensure_ascii (bool) – If True, the output is guaranteed to have all incoming non-ASCII characters escaped. If False (the default), these characters will be output as-is.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to include in the JSON output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to exclude from the JSON output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to serialize using field aliases.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A JSON string representation of the model.

Return type:

str

model_post_init(_BaseOperation__context: Any) None

Initialize logging and memory tracking after model construction.

Replaces the legacy __init__ body: creates the per-class logger and, when that logger is enabled for INFO level or higher, starts tracemalloc so per-operation memory usage can be logged.

Parameters:
  • __context – Pydantic post-init context (unused).

  • _BaseOperation__context (Any)

Return type:

None

to_json(filepath: str | Path | None = None) str | None

Serialize this operation to JSON.

Captures the operation as a {"class", "params"} envelope: params is model_dump(mode="json") (every declared field, including nested operations and raw arrays; PrivateAttr state such as loggers and timing is excluded automatically), and class records the concrete class name so from_json() can rebuild the right subclass. This mirrors ImagePipeline.to_json().

Parameters:

filepath (str | Path | None) – Optional path to write the JSON to. When None, the JSON string is returned instead. Accepts a str or Path.

Returns:

The JSON string when filepath is None, otherwise None.

Return type:

str | None

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.detect import OtsuDetector
>>> from phenotypic.sdk_ import CONFIG_SUFFIX_OPERATION, ensure_typed_json_suffix
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     saved = ensure_typed_json_suffix(p, CONFIG_SUFFIX_OPERATION)
...     OtsuDetector(ignore_zeros=True).to_json(p)
...     loaded = OtsuDetector.from_json(saved)
>>> loaded.ignore_zeros
True
widget(image: Image | None = None, show: bool = False) Widget

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.

axis: Annotated[int, TuneSpec(tunable=False)]
mode: str
model_computed_fields = {}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_extra: dict[str, Any] | None

Get extra fields set during validation.

Returns:

A dictionary of extra fields, or None if config.extra is not set to “allow”.

model_fields = {'axis': FieldInfo(annotation=int, required=False, default=0, description='Alignment axis. ``0`` regresses centroid positions within each row to correct horizontal skew; ``1`` regresses within each column to correct vertical skew. Default: ``0``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'mode': FieldInfo(annotation=str, required=False, default='edge', description="Edge-fill strategy passed to the image rotation. ``'edge'`` replicates the nearest border pixel (avoids dark corners); ``'constant'`` fills with zeros. Default: ``'edge'``.")}
property model_fields_set: set[str]

Returns the set of fields that have been explicitly set on this model instance.

Returns:

A set of strings representing the fields that have been set,

i.e. that were not filled from defaults.

class phenotypic.correction.ImageCropper(*, left: Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None, right: Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None, top: Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None, bottom: Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None)[source]

Bases: ImageCorrector

Remove pixels from image edges by specifying per-edge crop margins.

Crops all image components (rgb, gray, detect_mat, objmask, objmap) simultaneously using the same margins, so every layer remains spatially synchronised. When applied to a GridImage, the grid structure and finder are preserved and well positions are recalculated for the reduced dimensions.

For usage context, see How To: Crop and Pad Images for Batch Consistency.

Best For:
  • Removing scanner margins or plate borders that lie outside the agar surface before detection.

  • Eliminating edge artefacts such as bent agar, labelling tape, or moisture condensation that would generate false detections.

  • Standardising image dimensions across a batch of plates captured with slightly different positioning.

  • Isolating a sub-region of a large plate image for focused analysis.

Consider Also:
  • ImagePadder for extending image dimensions rather than reducing them.

  • RemoveBorderObjects when the goal is to exclude edge-touching colonies from analysis without altering image dimensions.

  • GridAligner when rotation correction is needed alongside cropping.

Parameters:
  • left (Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Pixels to remove from the left edge. None applies no cropping on this edge. Size to the off-agar margin you want to discard. Default: None.

  • right (Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Pixels to remove from the right edge. None applies no cropping on this edge. Default: None.

  • top (Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Pixels to remove from the top edge. None applies no cropping on this edge. Default: None.

  • bottom (Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Pixels to remove from the bottom edge. None applies no cropping on this edge. Default: None.

Returns:

Input image with all components cropped to the specified margins. GridImage grid positions are recalculated on the cropped dimensions.

Return type:

Image

Raises:
  • ValueError – If any margin is negative.

  • ValueError – If opposite margins together exceed the image dimension (e.g., top + bottom >= image height).

See also

How To: Crop and Pad Images for Batch Consistency for a visual walkthrough of cropping and padding operations on plate images. How To: Correct Grid Rotation for combining cropping with rotation correction.

classmethod __get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler, /) JsonSchemaValue

Hook into generating the model’s JSON schema.

Parameters:
  • core_schema (CoreSchema) – A pydantic-core CoreSchema. You can ignore this argument and call the handler with a new CoreSchema, wrap this CoreSchema ({‘type’: ‘nullable’, ‘schema’: current_schema}), or just call the handler with the original schema.

  • handler (GetJsonSchemaHandler) – Call into Pydantic’s internal JSON schema generation. This will raise a pydantic.errors.PydanticInvalidForJsonSchema if JSON schema generation fails. Since this gets called by BaseModel.model_json_schema you can override the schema_generator argument to that function to change JSON schema generation globally for a type.

Returns:

A JSON schema, as a Python object.

Return type:

JsonSchemaValue

classmethod __pydantic_init_subclass__(**kwargs: Any) None

Populate field descriptions from the subclass docstring.

Runs once per concrete subclass after pydantic has built its model. Copies parameter descriptions parsed from the Google-style Args: docstring block onto each field’s description slot so they surface in model_json_schema() — the machine-readable contract used by downstream tooling (e.g. an MCP server).

Parameters:

**kwargs (Any) – Class-keyword arguments forwarded by pydantic.

Return type:

None

classmethod __pydantic_on_complete__() None

This is called once the class and its fields are fully initialized and ready to be used.

This typically happens when the class is created (just before [__pydantic_init_subclass__()][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass), except when forward annotations are used that could not immediately be resolved. In that case, it will be called later, when the model is rebuilt automatically or explicitly using [model_rebuild()][pydantic.main.BaseModel.model_rebuild].

Return type:

None

classmethod construct(_fields_set: set[str] | None = None, **values: Any) Self
Parameters:
Return type:

Self

classmethod from_json(json_data: str | Path | dict) BaseOperation

Reconstruct an operation from JSON written by to_json().

Accepts a JSON string, a path to a JSON file, or a pre-parsed envelope dict (same input handling as ImagePipeline.from_json()). Polymorphic: ImageOperation.from_json(path) returns whatever concrete operation the file holds. When called on a narrower subclass, the resolved class must be a subclass of it, else a TypeError is raised.

Parameters:

json_data (str | Path | dict) – A JSON string, path to a JSON file, or envelope dict.

Returns:

The reconstructed operation instance.

Raises:
  • AttributeError – If the recorded class cannot be resolved in the phenotypic namespace.

  • TypeError – If called on a concrete subclass and the file holds a class that is not a subclass of it.

Return type:

BaseOperation

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.abc_ import ImageOperation
>>> from phenotypic.detect import OtsuDetector
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     OtsuDetector().to_json(p)
...     loaded = ImageOperation.from_json(p)  # polymorphic
>>> type(loaded).__name__
'OtsuDetector'
classmethod from_orm(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod model_construct(_fields_set: set[str] | None = None, **values: Any) Self

Creates a new instance of the Model class with validated data.

Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed.

!!! note

model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == ‘allow’, then all extra passed values are added to the model instance’s __dict__ and __pydantic_extra__ fields. If model_config.extra == ‘ignore’ (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == ‘forbid’ does not result in an error if extra values are passed, but they will be ignored.

Parameters:
  • _fields_set (set[str] | None) – A set of field names that were originally explicitly set during instantiation. If provided, this is directly used for the [model_fields_set][pydantic.BaseModel.model_fields_set] attribute. Otherwise, the field names from the values argument will be used.

  • values (Any) – Trusted or pre-validated data dictionary.

Returns:

A new instance of the Model class with validated data.

Return type:

Self

classmethod model_json_schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}', schema_generator: type[~pydantic.json_schema.GenerateJsonSchema] = <class 'pydantic.json_schema.GenerateJsonSchema'>, mode: ~typing.Literal['validation', 'serialization'] = 'validation', *, union_format: ~typing.Literal['any_of', 'primitive_type_array'] = 'any_of') dict[str, Any]

Generates a JSON schema for a model class.

Parameters:
  • by_alias (bool) – Whether to use attribute aliases or not.

  • ref_template (str) – The reference template.

  • union_format (Literal['any_of', 'primitive_type_array']) –

    The format to use when combining schemas from unions together. Can be one of:

    keyword to combine schemas (the default). - ‘primitive_type_array’: Use the [type](https://json-schema.org/understanding-json-schema/reference/type) keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive type (string, boolean, null, integer or number) or contains constraints/metadata, falls back to any_of.

  • schema_generator (type[GenerateJsonSchema]) – To override the logic used to generate the JSON schema, as a subclass of GenerateJsonSchema with your desired modifications

  • mode (Literal['validation', 'serialization']) – The mode in which to generate the schema.

Returns:

The JSON schema for the given model class.

Return type:

dict[str, Any]

classmethod model_parametrized_name(params: tuple[type[Any], ...]) str

Compute the class name for parametrizations of generic classes.

This method can be overridden to achieve a custom naming scheme for generic BaseModels.

Parameters:

params (tuple[type[Any], ...]) – Tuple of types of the class. Given a generic class Model with 2 type variables and a concrete model Model[str, int], the value (str, int) would be passed to params.

Returns:

String representing the new class where params are passed to cls as type variables.

Raises:

TypeError – Raised when trying to generate concrete names for non-generic models.

Return type:

str

classmethod model_rebuild(*, force: bool = False, raise_errors: bool = True, _parent_namespace_depth: int = 2, _types_namespace: MappingNamespace | None = None) bool | None

Try to rebuild the pydantic-core schema for the model.

This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.

Parameters:
  • force (bool) – Whether to force the rebuilding of the model schema, defaults to False.

  • raise_errors (bool) – Whether to raise errors, defaults to True.

  • _parent_namespace_depth (int) – The depth level of the parent namespace, defaults to 2.

  • _types_namespace (MappingNamespace | None) – The types namespace, defaults to None.

Returns:

Returns None if the schema is already “complete” and rebuilding was not required. If rebuilding _was_ required, returns True if rebuilding was successful, otherwise False.

Return type:

bool | None

classmethod model_validate(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, from_attributes: bool | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate a pydantic model instance.

Parameters:
  • obj (Any) – The object to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • from_attributes (bool | None) – Whether to extract data from object attributes.

  • context (Any | None) – Additional context to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Raises:

ValidationError – If the object could not be validated.

Returns:

The validated model instance.

Return type:

Self

classmethod model_validate_json(json_data: str | bytes | bytearray, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self
!!! abstract “Usage Documentation”

[JSON Parsing](../concepts/json.md#json-parsing)

Validate the given JSON data against the Pydantic model.

Parameters:
  • json_data (str | bytes | bytearray) – The JSON data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Raises:

ValidationError – If json_data is not a JSON string or the object could not be validated.

Return type:

Self

classmethod model_validate_strings(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate the given object with string data against the Pydantic model.

Parameters:
  • obj (Any) – The object containing string data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Return type:

Self

classmethod parse_file(path: str | Path, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • path (str | Path)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod parse_obj(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod parse_raw(b: str | bytes, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • b (str | bytes)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}') Dict[str, Any]
Parameters:
  • by_alias (bool)

  • ref_template (str)

Return type:

Dict[str, Any]

classmethod schema_json(*, by_alias: bool = True, ref_template: str = '#/$defs/{model}', **dumps_kwargs: Any) str
Parameters:
  • by_alias (bool)

  • ref_template (str)

  • dumps_kwargs (Any)

Return type:

str

classmethod update_forward_refs(**localns: Any) None
Parameters:

localns (Any)

Return type:

None

classmethod validate(value: Any) Self
Parameters:

value (Any)

Return type:

Self

__copy__() Self

Returns a shallow copy of the model.

Return type:

Self

__deepcopy__(memo: dict[int, Any] | None = None) Self

Returns a deep copy of the model.

Parameters:

memo (dict[int, Any] | None)

Return type:

Self

__del__()

Automatically stop tracemalloc when the object is deleted.

__init__(**data: Any) None

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:

data (Any)

Return type:

None

__iter__() Generator[tuple[str, Any], None, None]

So dict(model) works.

Return type:

Generator[tuple[str, Any], None, None]

__pretty__(fmt: Callable[[Any], Any], **kwargs: Any) Generator[Any]

Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects.

Parameters:
Return type:

Generator[Any]

__repr_name__() str

Name of the instance’s class, used in __repr__.

Return type:

str

__repr_recursion__(object: Any) str

Returns the string representation of a recursive object.

Parameters:

object (Any)

Return type:

str

__rich_repr__() RichReprResult

Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects.

Return type:

RichReprResult

apply(image: Image, inplace: bool = False) Image

Applies the operation to an image, either in-place or on a copy.

Parameters:
  • image (Image) – The arr image to apply the operation on.

  • inplace (bool) – If True, modifies the image in place; otherwise, operates on a copy of the image.

Returns:

The modified image after applying the operation.

Return type:

Image

copy(*, include: AbstractSetIntStr | MappingIntStrAny | None = None, exclude: AbstractSetIntStr | MappingIntStrAny | None = None, update: Dict[str, Any] | None = None, deep: bool = False) Self

Returns a copy of the model.

!!! warning “Deprecated”

This method is now deprecated; use model_copy instead.

If you need include or exclude, use:

`python {test="skip" lint="skip"} data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = {**data, **(update or {})} copied = self.model_validate(data) `

Parameters:
  • include (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to include in the copied model.

  • exclude (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to exclude in the copied model.

  • update (Dict[str, Any] | None) – Optional dictionary of field-value pairs to override field values in the copied model.

  • deep (bool) – If True, the values of fields that are Pydantic models will be deep-copied.

Returns:

A copy of the model with included, excluded and updated fields as specified.

Return type:

Self

dict(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False) Dict[str, Any]
Parameters:
Return type:

Dict[str, Any]

json(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Callable[[Any], Any] | None = PydanticUndefined, models_as_dict: bool = PydanticUndefined, **dumps_kwargs: Any) str
Parameters:
Return type:

str

model_copy(*, update: Mapping[str, Any] | None = None, deep: bool = False) Self
!!! abstract “Usage Documentation”

[model_copy](../concepts/models.md#model-copy)

Returns a copy of the model.

!!! note

The underlying instance’s [__dict__][object.__dict__] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).

Parameters:
  • update (Mapping[str, Any] | None) – Values to change/add in the new model. Note: the data is not validated before creating the new model. You should trust this data.

  • deep (bool) – Set to True to make a deep copy of the model.

Returns:

New model instance.

Return type:

Self

model_dump(*, mode: Literal['json', 'python'] | str = 'python', include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) dict[str, Any]
!!! abstract “Usage Documentation”

[model_dump](../concepts/serialization.md#python-mode)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Parameters:
  • mode (Literal['json', 'python'] | str) – The mode in which to_python should run. If mode is ‘json’, the output will only contain JSON serializable types. If mode is ‘python’, the output may contain non-JSON-serializable Python objects.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to include in the output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to exclude from the output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to use the field’s alias in the dictionary key if defined.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A dictionary representation of the model.

Return type:

dict[str, Any]

model_dump_json(*, indent: int | None = None, ensure_ascii: bool = False, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) str
!!! abstract “Usage Documentation”

[model_dump_json](../concepts/serialization.md#json-mode)

Generates a JSON representation of the model using Pydantic’s to_json method.

Parameters:
  • indent (int | None) – Indentation to use in the JSON output. If None is passed, the output will be compact.

  • ensure_ascii (bool) – If True, the output is guaranteed to have all incoming non-ASCII characters escaped. If False (the default), these characters will be output as-is.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to include in the JSON output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to exclude from the JSON output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to serialize using field aliases.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A JSON string representation of the model.

Return type:

str

model_post_init(_BaseOperation__context: Any) None

Initialize logging and memory tracking after model construction.

Replaces the legacy __init__ body: creates the per-class logger and, when that logger is enabled for INFO level or higher, starts tracemalloc so per-operation memory usage can be logged.

Parameters:
  • __context – Pydantic post-init context (unused).

  • _BaseOperation__context (Any)

Return type:

None

to_json(filepath: str | Path | None = None) str | None

Serialize this operation to JSON.

Captures the operation as a {"class", "params"} envelope: params is model_dump(mode="json") (every declared field, including nested operations and raw arrays; PrivateAttr state such as loggers and timing is excluded automatically), and class records the concrete class name so from_json() can rebuild the right subclass. This mirrors ImagePipeline.to_json().

Parameters:

filepath (str | Path | None) – Optional path to write the JSON to. When None, the JSON string is returned instead. Accepts a str or Path.

Returns:

The JSON string when filepath is None, otherwise None.

Return type:

str | None

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.detect import OtsuDetector
>>> from phenotypic.sdk_ import CONFIG_SUFFIX_OPERATION, ensure_typed_json_suffix
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     saved = ensure_typed_json_suffix(p, CONFIG_SUFFIX_OPERATION)
...     OtsuDetector(ignore_zeros=True).to_json(p)
...     loaded = OtsuDetector.from_json(saved)
>>> loaded.ignore_zeros
True
widget(image: Image | None = None, show: bool = False) Widget

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.

bottom: Annotated[int | None, TuneSpec(tunable=False)]
left: Annotated[int | None, TuneSpec(tunable=False)]
model_computed_fields = {}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_extra: dict[str, Any] | None

Get extra fields set during validation.

Returns:

A dictionary of extra fields, or None if config.extra is not set to “allow”.

model_fields = {'bottom': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, description='Pixels to remove from the bottom edge. ``None`` applies no cropping on this edge. Default: ``None``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'left': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, description='Pixels to remove from the left edge. ``None`` applies no cropping on this edge. Size to the off-agar margin you want to discard. Default: ``None``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'right': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, description='Pixels to remove from the right edge. ``None`` applies no cropping on this edge. Default: ``None``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'top': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, description='Pixels to remove from the top edge. ``None`` applies no cropping on this edge. Default: ``None``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)])}
property model_fields_set: set[str]

Returns the set of fields that have been explicitly set on this model instance.

Returns:

A set of strings representing the fields that have been set,

i.e. that were not filled from defaults.

right: Annotated[int | None, TuneSpec(tunable=False)]
top: Annotated[int | None, TuneSpec(tunable=False)]
class phenotypic.correction.ImagePadder(*, left: Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None, right: Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None, top: Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None, bottom: Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = None, mode: Literal['constant', 'edge', 'reflect', 'symmetric', 'wrap', 'linear_ramp', 'maximum', 'mean', 'median', 'minimum', 'empty'] = 'constant', constant_value: int | float = 0)[source]

Bases: ImageCorrector

Extend image dimensions by adding pixels to any combination of edges.

Pads the image on the left, right, top, and/or bottom using a configurable fill mode. All image components (RGB, gray, detect_mat, objmap) are padded in sync; the object map is always zero-padded regardless of mode to preserve integer label integrity. When applied to a GridImage, grid structure is preserved and well positions are recalculated automatically on the extended dimensions.

For usage context, see How To: Crop and Pad Images for Batch Consistency.

Best For:
  • Adding safety margins before rotation so corner colonies are not clipped by the fill boundary during rotation.

  • Standardising image dimensions across a batch when plates were positioned inconsistently in the scanner.

  • Creating border space when colonies grow near plate edges, improving subsequent grid detection accuracy.

  • Pre-processing before convolution-based enhancers that produce boundary artefacts on tight image borders.

Consider Also:
  • ImageCropper when the goal is to reduce image dimensions rather than extend them.

  • GridAligner for correcting plate rotation, which is typically paired with padding to protect corner colonies.

Parameters:
  • left (Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Pixels to add on the left edge. None applies no padding. Size to the artifact being protected (e.g. a margin wider than the largest expected rotation shift). Default: None.

  • right (Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Pixels to add on the right edge. None applies no padding. Default: None.

  • top (Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Pixels to add on the top edge. None applies no padding. Default: None.

  • bottom (Annotated[int | None, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Pixels to add on the bottom edge. None applies no padding. Default: None.

  • mode (Literal['constant', 'edge', 'reflect', 'symmetric', 'wrap', 'linear_ramp', 'maximum', 'mean', 'median', 'minimum', 'empty']) – Fill strategy passed to np.pad. Accepted values: 'constant', 'edge', 'reflect', 'symmetric', 'wrap', 'linear_ramp', 'maximum', 'mean', 'median', 'minimum', 'empty'. 'edge' replicates the nearest border pixel (safest for colony analysis); 'reflect' reduces convolution boundary artefacts; 'constant' fills with a uniform value. Default: 'constant'.

  • constant_value (int | float) – Fill value used when mode='constant'. Use 0 for black borders or 255 for white borders matching bright-agar backgrounds. Default: 0.

Returns:

Input image with all components padded by the specified amounts. GridImage grid positions are recalculated on the extended dimensions.

Return type:

Image

Raises:
  • ValueError – If any padding value is negative.

  • ValueError – If mode is not a recognised np.pad mode.

See also

How To: Crop and Pad Images for Batch Consistency for a visual walkthrough of padding and cropping plate images. How To: Correct Grid Rotation for combining padding with rotation correction.

classmethod __get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler, /) JsonSchemaValue

Hook into generating the model’s JSON schema.

Parameters:
  • core_schema (CoreSchema) – A pydantic-core CoreSchema. You can ignore this argument and call the handler with a new CoreSchema, wrap this CoreSchema ({‘type’: ‘nullable’, ‘schema’: current_schema}), or just call the handler with the original schema.

  • handler (GetJsonSchemaHandler) – Call into Pydantic’s internal JSON schema generation. This will raise a pydantic.errors.PydanticInvalidForJsonSchema if JSON schema generation fails. Since this gets called by BaseModel.model_json_schema you can override the schema_generator argument to that function to change JSON schema generation globally for a type.

Returns:

A JSON schema, as a Python object.

Return type:

JsonSchemaValue

classmethod __pydantic_init_subclass__(**kwargs: Any) None

Populate field descriptions from the subclass docstring.

Runs once per concrete subclass after pydantic has built its model. Copies parameter descriptions parsed from the Google-style Args: docstring block onto each field’s description slot so they surface in model_json_schema() — the machine-readable contract used by downstream tooling (e.g. an MCP server).

Parameters:

**kwargs (Any) – Class-keyword arguments forwarded by pydantic.

Return type:

None

classmethod __pydantic_on_complete__() None

This is called once the class and its fields are fully initialized and ready to be used.

This typically happens when the class is created (just before [__pydantic_init_subclass__()][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass), except when forward annotations are used that could not immediately be resolved. In that case, it will be called later, when the model is rebuilt automatically or explicitly using [model_rebuild()][pydantic.main.BaseModel.model_rebuild].

Return type:

None

classmethod construct(_fields_set: set[str] | None = None, **values: Any) Self
Parameters:
Return type:

Self

classmethod from_json(json_data: str | Path | dict) BaseOperation

Reconstruct an operation from JSON written by to_json().

Accepts a JSON string, a path to a JSON file, or a pre-parsed envelope dict (same input handling as ImagePipeline.from_json()). Polymorphic: ImageOperation.from_json(path) returns whatever concrete operation the file holds. When called on a narrower subclass, the resolved class must be a subclass of it, else a TypeError is raised.

Parameters:

json_data (str | Path | dict) – A JSON string, path to a JSON file, or envelope dict.

Returns:

The reconstructed operation instance.

Raises:
  • AttributeError – If the recorded class cannot be resolved in the phenotypic namespace.

  • TypeError – If called on a concrete subclass and the file holds a class that is not a subclass of it.

Return type:

BaseOperation

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.abc_ import ImageOperation
>>> from phenotypic.detect import OtsuDetector
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     OtsuDetector().to_json(p)
...     loaded = ImageOperation.from_json(p)  # polymorphic
>>> type(loaded).__name__
'OtsuDetector'
classmethod from_orm(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod model_construct(_fields_set: set[str] | None = None, **values: Any) Self

Creates a new instance of the Model class with validated data.

Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed.

!!! note

model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == ‘allow’, then all extra passed values are added to the model instance’s __dict__ and __pydantic_extra__ fields. If model_config.extra == ‘ignore’ (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == ‘forbid’ does not result in an error if extra values are passed, but they will be ignored.

Parameters:
  • _fields_set (set[str] | None) – A set of field names that were originally explicitly set during instantiation. If provided, this is directly used for the [model_fields_set][pydantic.BaseModel.model_fields_set] attribute. Otherwise, the field names from the values argument will be used.

  • values (Any) – Trusted or pre-validated data dictionary.

Returns:

A new instance of the Model class with validated data.

Return type:

Self

classmethod model_json_schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}', schema_generator: type[~pydantic.json_schema.GenerateJsonSchema] = <class 'pydantic.json_schema.GenerateJsonSchema'>, mode: ~typing.Literal['validation', 'serialization'] = 'validation', *, union_format: ~typing.Literal['any_of', 'primitive_type_array'] = 'any_of') dict[str, Any]

Generates a JSON schema for a model class.

Parameters:
  • by_alias (bool) – Whether to use attribute aliases or not.

  • ref_template (str) – The reference template.

  • union_format (Literal['any_of', 'primitive_type_array']) –

    The format to use when combining schemas from unions together. Can be one of:

    keyword to combine schemas (the default). - ‘primitive_type_array’: Use the [type](https://json-schema.org/understanding-json-schema/reference/type) keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive type (string, boolean, null, integer or number) or contains constraints/metadata, falls back to any_of.

  • schema_generator (type[GenerateJsonSchema]) – To override the logic used to generate the JSON schema, as a subclass of GenerateJsonSchema with your desired modifications

  • mode (Literal['validation', 'serialization']) – The mode in which to generate the schema.

Returns:

The JSON schema for the given model class.

Return type:

dict[str, Any]

classmethod model_parametrized_name(params: tuple[type[Any], ...]) str

Compute the class name for parametrizations of generic classes.

This method can be overridden to achieve a custom naming scheme for generic BaseModels.

Parameters:

params (tuple[type[Any], ...]) – Tuple of types of the class. Given a generic class Model with 2 type variables and a concrete model Model[str, int], the value (str, int) would be passed to params.

Returns:

String representing the new class where params are passed to cls as type variables.

Raises:

TypeError – Raised when trying to generate concrete names for non-generic models.

Return type:

str

classmethod model_rebuild(*, force: bool = False, raise_errors: bool = True, _parent_namespace_depth: int = 2, _types_namespace: MappingNamespace | None = None) bool | None

Try to rebuild the pydantic-core schema for the model.

This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.

Parameters:
  • force (bool) – Whether to force the rebuilding of the model schema, defaults to False.

  • raise_errors (bool) – Whether to raise errors, defaults to True.

  • _parent_namespace_depth (int) – The depth level of the parent namespace, defaults to 2.

  • _types_namespace (MappingNamespace | None) – The types namespace, defaults to None.

Returns:

Returns None if the schema is already “complete” and rebuilding was not required. If rebuilding _was_ required, returns True if rebuilding was successful, otherwise False.

Return type:

bool | None

classmethod model_validate(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, from_attributes: bool | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate a pydantic model instance.

Parameters:
  • obj (Any) – The object to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • from_attributes (bool | None) – Whether to extract data from object attributes.

  • context (Any | None) – Additional context to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Raises:

ValidationError – If the object could not be validated.

Returns:

The validated model instance.

Return type:

Self

classmethod model_validate_json(json_data: str | bytes | bytearray, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self
!!! abstract “Usage Documentation”

[JSON Parsing](../concepts/json.md#json-parsing)

Validate the given JSON data against the Pydantic model.

Parameters:
  • json_data (str | bytes | bytearray) – The JSON data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Raises:

ValidationError – If json_data is not a JSON string or the object could not be validated.

Return type:

Self

classmethod model_validate_strings(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate the given object with string data against the Pydantic model.

Parameters:
  • obj (Any) – The object containing string data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Return type:

Self

classmethod parse_file(path: str | Path, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • path (str | Path)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod parse_obj(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod parse_raw(b: str | bytes, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • b (str | bytes)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}') Dict[str, Any]
Parameters:
  • by_alias (bool)

  • ref_template (str)

Return type:

Dict[str, Any]

classmethod schema_json(*, by_alias: bool = True, ref_template: str = '#/$defs/{model}', **dumps_kwargs: Any) str
Parameters:
  • by_alias (bool)

  • ref_template (str)

  • dumps_kwargs (Any)

Return type:

str

classmethod update_forward_refs(**localns: Any) None
Parameters:

localns (Any)

Return type:

None

classmethod validate(value: Any) Self
Parameters:

value (Any)

Return type:

Self

__copy__() Self

Returns a shallow copy of the model.

Return type:

Self

__deepcopy__(memo: dict[int, Any] | None = None) Self

Returns a deep copy of the model.

Parameters:

memo (dict[int, Any] | None)

Return type:

Self

__del__()

Automatically stop tracemalloc when the object is deleted.

__init__(**data: Any) None

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:

data (Any)

Return type:

None

__iter__() Generator[tuple[str, Any], None, None]

So dict(model) works.

Return type:

Generator[tuple[str, Any], None, None]

__pretty__(fmt: Callable[[Any], Any], **kwargs: Any) Generator[Any]

Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects.

Parameters:
Return type:

Generator[Any]

__repr_name__() str

Name of the instance’s class, used in __repr__.

Return type:

str

__repr_recursion__(object: Any) str

Returns the string representation of a recursive object.

Parameters:

object (Any)

Return type:

str

__rich_repr__() RichReprResult

Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects.

Return type:

RichReprResult

apply(image: Image, inplace: bool = False) Image

Applies the operation to an image, either in-place or on a copy.

Parameters:
  • image (Image) – The arr image to apply the operation on.

  • inplace (bool) – If True, modifies the image in place; otherwise, operates on a copy of the image.

Returns:

The modified image after applying the operation.

Return type:

Image

copy(*, include: AbstractSetIntStr | MappingIntStrAny | None = None, exclude: AbstractSetIntStr | MappingIntStrAny | None = None, update: Dict[str, Any] | None = None, deep: bool = False) Self

Returns a copy of the model.

!!! warning “Deprecated”

This method is now deprecated; use model_copy instead.

If you need include or exclude, use:

`python {test="skip" lint="skip"} data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = {**data, **(update or {})} copied = self.model_validate(data) `

Parameters:
  • include (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to include in the copied model.

  • exclude (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to exclude in the copied model.

  • update (Dict[str, Any] | None) – Optional dictionary of field-value pairs to override field values in the copied model.

  • deep (bool) – If True, the values of fields that are Pydantic models will be deep-copied.

Returns:

A copy of the model with included, excluded and updated fields as specified.

Return type:

Self

dict(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False) Dict[str, Any]
Parameters:
Return type:

Dict[str, Any]

json(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Callable[[Any], Any] | None = PydanticUndefined, models_as_dict: bool = PydanticUndefined, **dumps_kwargs: Any) str
Parameters:
Return type:

str

model_copy(*, update: Mapping[str, Any] | None = None, deep: bool = False) Self
!!! abstract “Usage Documentation”

[model_copy](../concepts/models.md#model-copy)

Returns a copy of the model.

!!! note

The underlying instance’s [__dict__][object.__dict__] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).

Parameters:
  • update (Mapping[str, Any] | None) – Values to change/add in the new model. Note: the data is not validated before creating the new model. You should trust this data.

  • deep (bool) – Set to True to make a deep copy of the model.

Returns:

New model instance.

Return type:

Self

model_dump(*, mode: Literal['json', 'python'] | str = 'python', include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) dict[str, Any]
!!! abstract “Usage Documentation”

[model_dump](../concepts/serialization.md#python-mode)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Parameters:
  • mode (Literal['json', 'python'] | str) – The mode in which to_python should run. If mode is ‘json’, the output will only contain JSON serializable types. If mode is ‘python’, the output may contain non-JSON-serializable Python objects.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to include in the output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to exclude from the output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to use the field’s alias in the dictionary key if defined.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A dictionary representation of the model.

Return type:

dict[str, Any]

model_dump_json(*, indent: int | None = None, ensure_ascii: bool = False, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) str
!!! abstract “Usage Documentation”

[model_dump_json](../concepts/serialization.md#json-mode)

Generates a JSON representation of the model using Pydantic’s to_json method.

Parameters:
  • indent (int | None) – Indentation to use in the JSON output. If None is passed, the output will be compact.

  • ensure_ascii (bool) – If True, the output is guaranteed to have all incoming non-ASCII characters escaped. If False (the default), these characters will be output as-is.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to include in the JSON output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to exclude from the JSON output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to serialize using field aliases.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A JSON string representation of the model.

Return type:

str

model_post_init(_BaseOperation__context: Any) None

Initialize logging and memory tracking after model construction.

Replaces the legacy __init__ body: creates the per-class logger and, when that logger is enabled for INFO level or higher, starts tracemalloc so per-operation memory usage can be logged.

Parameters:
  • __context – Pydantic post-init context (unused).

  • _BaseOperation__context (Any)

Return type:

None

to_json(filepath: str | Path | None = None) str | None

Serialize this operation to JSON.

Captures the operation as a {"class", "params"} envelope: params is model_dump(mode="json") (every declared field, including nested operations and raw arrays; PrivateAttr state such as loggers and timing is excluded automatically), and class records the concrete class name so from_json() can rebuild the right subclass. This mirrors ImagePipeline.to_json().

Parameters:

filepath (str | Path | None) – Optional path to write the JSON to. When None, the JSON string is returned instead. Accepts a str or Path.

Returns:

The JSON string when filepath is None, otherwise None.

Return type:

str | None

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.detect import OtsuDetector
>>> from phenotypic.sdk_ import CONFIG_SUFFIX_OPERATION, ensure_typed_json_suffix
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     saved = ensure_typed_json_suffix(p, CONFIG_SUFFIX_OPERATION)
...     OtsuDetector(ignore_zeros=True).to_json(p)
...     loaded = OtsuDetector.from_json(saved)
>>> loaded.ignore_zeros
True
widget(image: Image | None = None, show: bool = False) Widget

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.

bottom: Annotated[int | None, TuneSpec(tunable=False)]
constant_value: int | float
left: Annotated[int | None, TuneSpec(tunable=False)]
mode: PadMode
model_computed_fields = {}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_extra: dict[str, Any] | None

Get extra fields set during validation.

Returns:

A dictionary of extra fields, or None if config.extra is not set to “allow”.

model_fields = {'bottom': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, description='Pixels to add on the bottom edge. ``None`` applies no padding.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'constant_value': FieldInfo(annotation=Union[int, float], required=False, default=0, description="Fill value used when ``mode='constant'``. Use ``0`` for black borders or ``255`` for white borders matching bright-agar backgrounds. Default: ``0``."), 'left': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, description='Pixels to add on the left edge. ``None`` applies no padding. Size to the artifact being protected (e.g. a margin wider than the largest expected rotation shift). Default: ``None``.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'mode': FieldInfo(annotation=Literal['constant', 'edge', 'reflect', 'symmetric', 'wrap', 'linear_ramp', 'maximum', 'mean', 'median', 'minimum', 'empty'], required=False, default='constant', description="Fill strategy passed to ``np.pad``. Accepted values: ``'constant'``, ``'edge'``, ``'reflect'``, ``'symmetric'``, ``'wrap'``, ``'linear_ramp'``, ``'maximum'``, ``'mean'``, ``'median'``, ``'minimum'``, ``'empty'``. ``'edge'`` replicates the nearest border pixel (safest for colony analysis); ``'reflect'`` reduces convolution boundary artefacts; ``'constant'`` fills with a uniform value. Default: ``'constant'``."), 'right': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, description='Pixels to add on the right edge. ``None`` applies no padding.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'top': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, description='Pixels to add on the top edge. ``None`` applies no padding.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)])}
property model_fields_set: set[str]

Returns the set of fields that have been explicitly set on this model instance.

Returns:

A set of strings representing the fields that have been set,

i.e. that were not filled from defaults.

right: Annotated[int | None, TuneSpec(tunable=False)]
top: Annotated[int | None, TuneSpec(tunable=False)]
class phenotypic.correction.VisuShrinkCorrector(*, use_gat: bool = False, gat_gain: Annotated[float, Gt(gt=0)] = 1.0, gat_mu: Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)] = 0.0, gat_read_sigma: Annotated[float, Ge(ge=0)] = 0.0, gat_scale_factor: Annotated[float | None, Gt(gt=0)] = None, sigma: Annotated[float | None, TuneSpec(low=0.01, high=0.1, step=None, log=True, categories=None, tunable=True)] = None, wavelet: str = 'db2', mode: Literal['soft', 'hard'] = 'soft', wavelet_levels: Annotated[int | None, TuneSpec(low=2, high=6, step=None, log=False, categories=None, tunable=True)] = None, convert2ycbcr: bool = True, rescale_sigma: bool = True, clip: bool = True)[source]

Bases: _GATSupportMixin, ImageCorrector

Denoise all image components using the near-minimax VisuShrink universal wavelet threshold.

Apply VisuShrink wavelet denoising to RGB (if present), grayscale, and detection matrix simultaneously, using a single global threshold derived from the estimated noise level and image size. All three image representations are updated in one pass, keeping them mutually consistent. The universal threshold is deliberately conservative and tends to over-smooth relative to adaptive alternatives.

For algorithm details, see What Enhancement Actually Does.

Best For:
  • Quick, consistent denoising of raw plate scans before archival or publication where a single noise level characterizes the whole image.

  • Plates with uniform scanner or camera noise where per-subband adaptation provides little additional benefit.

  • Removing broad-field scanner banding or read noise from all image components before downstream multi-channel analysis.

Consider Also:
  • BayesShrinkCorrector for adaptive per-subband thresholds that preserve finer colony detail at the cost of slightly more computation.

  • DenoiseBlockMatch for GAT-stabilized BM3D collaborative filtering when Poisson-Gaussian noise modelling is important.

  • VisuShrinkEnhancer when only the detection matrix should be denoised and RGB and gray must remain untouched.

Parameters:
  • sigma (Annotated[float | None, TuneSpec(low=0.01, high=0.1, step=None, log=True, categories=None, tunable=True)]) – Noise standard deviation on the [0, 1] intensity scale. None auto-estimates from the median absolute deviation of the finest wavelet detail subband (MAD / 0.6745). The universal threshold T = sigma * sqrt(2 * log(N)) is conservative; reducing sigma by factors of 2–4 below the auto-estimate gives sharper output. Internally retargeted to 1.0 for gray and detect_mat when use_gat=True; RGB is not GAT-wrapped. Default: None.

  • wavelet (str) – PyWavelets wavelet family name. 'db2' is general-purpose with compact support; 'db4' has more vanishing moments and wider support, representing smooth colony interiors more sparsely. Default: 'db2'.

  • mode (Literal['soft', 'hard']) – Wavelet coefficient thresholding mode. 'soft' shrinks surviving coefficients toward zero, producing smoother output preferred for detection preprocessing. 'hard' zeroes coefficients below the threshold and leaves the rest unchanged, retaining sharper edges but introducing discontinuities that can appear as ringing near sharp boundaries. Default: 'soft'.

  • wavelet_levels (Annotated[int | None, TuneSpec(low=2, high=6, step=None, log=False, categories=None, tunable=True)]) – Number of wavelet decomposition levels. None uses the library heuristic (maximum possible minus three). Practical manual range: 2–6. More levels suppress noise at coarser spatial scales; fewer levels restrict denoising to fine-grained noise. Default: None.

  • convert2ycbcr (bool) – Convert RGB to YCbCr before denoising so luminance and chrominance channels are thresholded independently, preserving colony hue for pigmentation assays. Applies only when RGB data is present. Default: True.

  • rescale_sigma (bool) – Allow skimage to internally rescale sigma when converting between dtypes. Automatically deferred to False during the gray and detect_mat passes when use_gat=True to prevent double-scaling the stabilized-domain noise level. Default: True.

  • clip (bool) – Clamp gray and detect_mat outputs to [0, 1] after denoising. Soft thresholding can produce marginally negative values near dark colony edges; clipping eliminates these. Automatically deferred to False inside the GAT region so the inverse transform operates on the full stabilized signal before the final clamp. Default: True.

  • parameters (# GAT)

  • use_gat (bool) – Wrap gray and detect_mat denoising in the Generalized Anscombe Transform, converting Poisson-Gaussian noise into approximately unit-variance Gaussian noise so the VisuShrink threshold is correctly scaled across intensity levels. RGB is not transformed. Enable for fluorescence plate readers or low-light incubator images. Default: False.

  • gat_gain (Annotated[float, Gt(gt=0)]) – Camera gain in electrons per ADU. Typical range: 0.5–10 e-/ADU depending on sensor. Obtain from the manufacturer datasheet or a mean-variance calibration. Default: 1.0.

  • gat_mu (Annotated[float, TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]) – Read-noise mean (dark-current baseline offset) in count units consistent with gat_scale_factor. Set to 0.0 when the image has been bias-subtracted, covering most flatbed-scanner workflows. Default: 0.0.

  • gat_read_sigma (Annotated[float, Ge(ge=0)]) – Read-noise standard deviation in count units consistent with gat_scale_factor. Zero assumes pure Poisson noise; supplying the sensor read-noise spec (a few to a few tens of counts for typical scientific CCDs) improves stabilization at low signal levels. Default: 0.0.

  • gat_scale_factor (Annotated[float | None, Gt(gt=0)]) – Multiplier converting normalized [0, 1] float data to photon counts before the forward GAT. None auto-detects from image bit depth (8-bit: 255, 16-bit: 65535). Override for non-standard bit depths such as 12-bit sensors stored in a 16-bit container (4095). Default: None.

Returns:

Input image with all components (rgb, gray, detect_mat) transformed by VisuShrink wavelet denoising. All three representations are updated in a single pass.

Return type:

Image

References

[1] D. L. Donoho and I. M. Johnstone, “Ideal spatial adaptation by wavelet shrinkage,” Biometrika, vol. 81, no. 3, pp. 425–455, Sep. 1994.

[2] M. Mäkitalo and A. Foi, “Optimal inversion of the generalized Anscombe transformation for Poisson-Gaussian noise,” IEEE Trans. Image Process., vol. 22, no. 1, pp. 91–103, Jan. 2013.

See also

How To: Denoise Low-Light Images for a visual walkthrough of wavelet denoising on plate images. Image Quality: Noise, Contrast, and Structure for background on noise models and denoising strategy selection.

classmethod __get_pydantic_json_schema__(core_schema: CoreSchema, handler: GetJsonSchemaHandler, /) JsonSchemaValue

Hook into generating the model’s JSON schema.

Parameters:
  • core_schema (CoreSchema) – A pydantic-core CoreSchema. You can ignore this argument and call the handler with a new CoreSchema, wrap this CoreSchema ({‘type’: ‘nullable’, ‘schema’: current_schema}), or just call the handler with the original schema.

  • handler (GetJsonSchemaHandler) – Call into Pydantic’s internal JSON schema generation. This will raise a pydantic.errors.PydanticInvalidForJsonSchema if JSON schema generation fails. Since this gets called by BaseModel.model_json_schema you can override the schema_generator argument to that function to change JSON schema generation globally for a type.

Returns:

A JSON schema, as a Python object.

Return type:

JsonSchemaValue

classmethod __pydantic_init_subclass__(**kwargs: Any) None

Populate field descriptions from the subclass docstring.

Runs once per concrete subclass after pydantic has built its model. Copies parameter descriptions parsed from the Google-style Args: docstring block onto each field’s description slot so they surface in model_json_schema() — the machine-readable contract used by downstream tooling (e.g. an MCP server).

Parameters:

**kwargs (Any) – Class-keyword arguments forwarded by pydantic.

Return type:

None

classmethod __pydantic_on_complete__() None

This is called once the class and its fields are fully initialized and ready to be used.

This typically happens when the class is created (just before [__pydantic_init_subclass__()][pydantic.main.BaseModel.__pydantic_init_subclass__] is called on the superclass), except when forward annotations are used that could not immediately be resolved. In that case, it will be called later, when the model is rebuilt automatically or explicitly using [model_rebuild()][pydantic.main.BaseModel.model_rebuild].

Return type:

None

classmethod construct(_fields_set: set[str] | None = None, **values: Any) Self
Parameters:
Return type:

Self

classmethod from_json(json_data: str | Path | dict) BaseOperation

Reconstruct an operation from JSON written by to_json().

Accepts a JSON string, a path to a JSON file, or a pre-parsed envelope dict (same input handling as ImagePipeline.from_json()). Polymorphic: ImageOperation.from_json(path) returns whatever concrete operation the file holds. When called on a narrower subclass, the resolved class must be a subclass of it, else a TypeError is raised.

Parameters:

json_data (str | Path | dict) – A JSON string, path to a JSON file, or envelope dict.

Returns:

The reconstructed operation instance.

Raises:
  • AttributeError – If the recorded class cannot be resolved in the phenotypic namespace.

  • TypeError – If called on a concrete subclass and the file holds a class that is not a subclass of it.

Return type:

BaseOperation

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.abc_ import ImageOperation
>>> from phenotypic.detect import OtsuDetector
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     OtsuDetector().to_json(p)
...     loaded = ImageOperation.from_json(p)  # polymorphic
>>> type(loaded).__name__
'OtsuDetector'
classmethod from_orm(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod model_construct(_fields_set: set[str] | None = None, **values: Any) Self

Creates a new instance of the Model class with validated data.

Creates a new model setting __dict__ and __pydantic_fields_set__ from trusted or pre-validated data. Default values are respected, but no other validation is performed.

!!! note

model_construct() generally respects the model_config.extra setting on the provided model. That is, if model_config.extra == ‘allow’, then all extra passed values are added to the model instance’s __dict__ and __pydantic_extra__ fields. If model_config.extra == ‘ignore’ (the default), then all extra passed values are ignored. Because no validation is performed with a call to model_construct(), having model_config.extra == ‘forbid’ does not result in an error if extra values are passed, but they will be ignored.

Parameters:
  • _fields_set (set[str] | None) – A set of field names that were originally explicitly set during instantiation. If provided, this is directly used for the [model_fields_set][pydantic.BaseModel.model_fields_set] attribute. Otherwise, the field names from the values argument will be used.

  • values (Any) – Trusted or pre-validated data dictionary.

Returns:

A new instance of the Model class with validated data.

Return type:

Self

classmethod model_json_schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}', schema_generator: type[~pydantic.json_schema.GenerateJsonSchema] = <class 'pydantic.json_schema.GenerateJsonSchema'>, mode: ~typing.Literal['validation', 'serialization'] = 'validation', *, union_format: ~typing.Literal['any_of', 'primitive_type_array'] = 'any_of') dict[str, Any]

Generates a JSON schema for a model class.

Parameters:
  • by_alias (bool) – Whether to use attribute aliases or not.

  • ref_template (str) – The reference template.

  • union_format (Literal['any_of', 'primitive_type_array']) –

    The format to use when combining schemas from unions together. Can be one of:

    keyword to combine schemas (the default). - ‘primitive_type_array’: Use the [type](https://json-schema.org/understanding-json-schema/reference/type) keyword as an array of strings, containing each type of the combination. If any of the schemas is not a primitive type (string, boolean, null, integer or number) or contains constraints/metadata, falls back to any_of.

  • schema_generator (type[GenerateJsonSchema]) – To override the logic used to generate the JSON schema, as a subclass of GenerateJsonSchema with your desired modifications

  • mode (Literal['validation', 'serialization']) – The mode in which to generate the schema.

Returns:

The JSON schema for the given model class.

Return type:

dict[str, Any]

classmethod model_parametrized_name(params: tuple[type[Any], ...]) str

Compute the class name for parametrizations of generic classes.

This method can be overridden to achieve a custom naming scheme for generic BaseModels.

Parameters:

params (tuple[type[Any], ...]) – Tuple of types of the class. Given a generic class Model with 2 type variables and a concrete model Model[str, int], the value (str, int) would be passed to params.

Returns:

String representing the new class where params are passed to cls as type variables.

Raises:

TypeError – Raised when trying to generate concrete names for non-generic models.

Return type:

str

classmethod model_rebuild(*, force: bool = False, raise_errors: bool = True, _parent_namespace_depth: int = 2, _types_namespace: MappingNamespace | None = None) bool | None

Try to rebuild the pydantic-core schema for the model.

This may be necessary when one of the annotations is a ForwardRef which could not be resolved during the initial attempt to build the schema, and automatic rebuilding fails.

Parameters:
  • force (bool) – Whether to force the rebuilding of the model schema, defaults to False.

  • raise_errors (bool) – Whether to raise errors, defaults to True.

  • _parent_namespace_depth (int) – The depth level of the parent namespace, defaults to 2.

  • _types_namespace (MappingNamespace | None) – The types namespace, defaults to None.

Returns:

Returns None if the schema is already “complete” and rebuilding was not required. If rebuilding _was_ required, returns True if rebuilding was successful, otherwise False.

Return type:

bool | None

classmethod model_validate(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, from_attributes: bool | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate a pydantic model instance.

Parameters:
  • obj (Any) – The object to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • from_attributes (bool | None) – Whether to extract data from object attributes.

  • context (Any | None) – Additional context to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Raises:

ValidationError – If the object could not be validated.

Returns:

The validated model instance.

Return type:

Self

classmethod model_validate_json(json_data: str | bytes | bytearray, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self
!!! abstract “Usage Documentation”

[JSON Parsing](../concepts/json.md#json-parsing)

Validate the given JSON data against the Pydantic model.

Parameters:
  • json_data (str | bytes | bytearray) – The JSON data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Raises:

ValidationError – If json_data is not a JSON string or the object could not be validated.

Return type:

Self

classmethod model_validate_strings(obj: Any, *, strict: bool | None = None, extra: Literal['allow', 'ignore', 'forbid'] | None = None, context: Any | None = None, by_alias: bool | None = None, by_name: bool | None = None) Self

Validate the given object with string data against the Pydantic model.

Parameters:
  • obj (Any) – The object containing string data to validate.

  • strict (bool | None) – Whether to enforce types strictly.

  • extra (Literal['allow', 'ignore', 'forbid'] | None) – Whether to ignore, allow, or forbid extra data during model validation. See the [extra configuration value][pydantic.ConfigDict.extra] for details.

  • context (Any | None) – Extra variables to pass to the validator.

  • by_alias (bool | None) – Whether to use the field’s alias when validating against the provided input data.

  • by_name (bool | None) – Whether to use the field’s name when validating against the provided input data.

Returns:

The validated Pydantic model.

Return type:

Self

classmethod parse_file(path: str | Path, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • path (str | Path)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod parse_obj(obj: Any) Self
Parameters:

obj (Any)

Return type:

Self

classmethod parse_raw(b: str | bytes, *, content_type: str | None = None, encoding: str = 'utf8', proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False) Self
Parameters:
  • b (str | bytes)

  • content_type (str | None)

  • encoding (str)

  • proto (DeprecatedParseProtocol | None)

  • allow_pickle (bool)

Return type:

Self

classmethod schema(by_alias: bool = True, ref_template: str = '#/$defs/{model}') Dict[str, Any]
Parameters:
  • by_alias (bool)

  • ref_template (str)

Return type:

Dict[str, Any]

classmethod schema_json(*, by_alias: bool = True, ref_template: str = '#/$defs/{model}', **dumps_kwargs: Any) str
Parameters:
  • by_alias (bool)

  • ref_template (str)

  • dumps_kwargs (Any)

Return type:

str

classmethod update_forward_refs(**localns: Any) None
Parameters:

localns (Any)

Return type:

None

classmethod validate(value: Any) Self
Parameters:

value (Any)

Return type:

Self

__copy__() Self

Returns a shallow copy of the model.

Return type:

Self

__deepcopy__(memo: dict[int, Any] | None = None) Self

Returns a deep copy of the model.

Parameters:

memo (dict[int, Any] | None)

Return type:

Self

__del__()

Automatically stop tracemalloc when the object is deleted.

__init__(**data: Any) None

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:

data (Any)

Return type:

None

__iter__() Generator[tuple[str, Any], None, None]

So dict(model) works.

Return type:

Generator[tuple[str, Any], None, None]

__pretty__(fmt: Callable[[Any], Any], **kwargs: Any) Generator[Any]

Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects.

Parameters:
Return type:

Generator[Any]

__repr_name__() str

Name of the instance’s class, used in __repr__.

Return type:

str

__repr_recursion__(object: Any) str

Returns the string representation of a recursive object.

Parameters:

object (Any)

Return type:

str

__rich_repr__() RichReprResult

Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects.

Return type:

RichReprResult

apply(image: Image, inplace: bool = False) Image

Applies the operation to an image, either in-place or on a copy.

Parameters:
  • image (Image) – The arr image to apply the operation on.

  • inplace (bool) – If True, modifies the image in place; otherwise, operates on a copy of the image.

Returns:

The modified image after applying the operation.

Return type:

Image

copy(*, include: AbstractSetIntStr | MappingIntStrAny | None = None, exclude: AbstractSetIntStr | MappingIntStrAny | None = None, update: Dict[str, Any] | None = None, deep: bool = False) Self

Returns a copy of the model.

!!! warning “Deprecated”

This method is now deprecated; use model_copy instead.

If you need include or exclude, use:

`python {test="skip" lint="skip"} data = self.model_dump(include=include, exclude=exclude, round_trip=True) data = {**data, **(update or {})} copied = self.model_validate(data) `

Parameters:
  • include (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to include in the copied model.

  • exclude (AbstractSetIntStr | MappingIntStrAny | None) – Optional set or mapping specifying which fields to exclude in the copied model.

  • update (Dict[str, Any] | None) – Optional dictionary of field-value pairs to override field values in the copied model.

  • deep (bool) – If True, the values of fields that are Pydantic models will be deep-copied.

Returns:

A copy of the model with included, excluded and updated fields as specified.

Return type:

Self

dict(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False) Dict[str, Any]
Parameters:
Return type:

Dict[str, Any]

json(*, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, by_alias: bool = False, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Callable[[Any], Any] | None = PydanticUndefined, models_as_dict: bool = PydanticUndefined, **dumps_kwargs: Any) str
Parameters:
Return type:

str

model_copy(*, update: Mapping[str, Any] | None = None, deep: bool = False) Self
!!! abstract “Usage Documentation”

[model_copy](../concepts/models.md#model-copy)

Returns a copy of the model.

!!! note

The underlying instance’s [__dict__][object.__dict__] attribute is copied. This might have unexpected side effects if you store anything in it, on top of the model fields (e.g. the value of [cached properties][functools.cached_property]).

Parameters:
  • update (Mapping[str, Any] | None) – Values to change/add in the new model. Note: the data is not validated before creating the new model. You should trust this data.

  • deep (bool) – Set to True to make a deep copy of the model.

Returns:

New model instance.

Return type:

Self

model_dump(*, mode: Literal['json', 'python'] | str = 'python', include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) dict[str, Any]
!!! abstract “Usage Documentation”

[model_dump](../concepts/serialization.md#python-mode)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Parameters:
  • mode (Literal['json', 'python'] | str) – The mode in which to_python should run. If mode is ‘json’, the output will only contain JSON serializable types. If mode is ‘python’, the output may contain non-JSON-serializable Python objects.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to include in the output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – A set of fields to exclude from the output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to use the field’s alias in the dictionary key if defined.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A dictionary representation of the model.

Return type:

dict[str, Any]

model_dump_json(*, indent: int | None = None, ensure_ascii: bool = False, include: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, exclude: set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None = None, context: Any | None = None, by_alias: bool | None = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, exclude_computed_fields: bool = False, round_trip: bool = False, warnings: bool | Literal['none', 'warn', 'error'] = True, fallback: Callable[[Any], Any] | None = None, serialize_as_any: bool = False) str
!!! abstract “Usage Documentation”

[model_dump_json](../concepts/serialization.md#json-mode)

Generates a JSON representation of the model using Pydantic’s to_json method.

Parameters:
  • indent (int | None) – Indentation to use in the JSON output. If None is passed, the output will be compact.

  • ensure_ascii (bool) – If True, the output is guaranteed to have all incoming non-ASCII characters escaped. If False (the default), these characters will be output as-is.

  • include (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to include in the JSON output.

  • exclude (set[int] | set[str] | Mapping[int, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | Mapping[str, set[int] | set[str] | Mapping[int, IncEx | bool] | Mapping[str, IncEx | bool] | bool] | None) – Field(s) to exclude from the JSON output.

  • context (Any | None) – Additional context to pass to the serializer.

  • by_alias (bool | None) – Whether to serialize using field aliases.

  • exclude_unset (bool) – Whether to exclude fields that have not been explicitly set.

  • exclude_defaults (bool) – Whether to exclude fields that are set to their default value.

  • exclude_none (bool) – Whether to exclude fields that have a value of None.

  • exclude_computed_fields (bool) – Whether to exclude computed fields. While this can be useful for round-tripping, it is usually recommended to use the dedicated round_trip parameter instead.

  • round_trip (bool) – If True, dumped values should be valid as input for non-idempotent types such as Json[T].

  • warnings (bool | Literal['none', 'warn', 'error']) – How to handle serialization errors. False/”none” ignores them, True/”warn” logs errors, “error” raises a [PydanticSerializationError][pydantic_core.PydanticSerializationError].

  • fallback (Callable[[Any], Any] | None) – A function to call when an unknown value is encountered. If not provided, a [PydanticSerializationError][pydantic_core.PydanticSerializationError] error is raised.

  • serialize_as_any (bool) – Whether to serialize fields with duck-typing serialization behavior.

Returns:

A JSON string representation of the model.

Return type:

str

model_post_init(_BaseOperation__context: Any) None

Initialize logging and memory tracking after model construction.

Replaces the legacy __init__ body: creates the per-class logger and, when that logger is enabled for INFO level or higher, starts tracemalloc so per-operation memory usage can be logged.

Parameters:
  • __context – Pydantic post-init context (unused).

  • _BaseOperation__context (Any)

Return type:

None

to_json(filepath: str | Path | None = None) str | None

Serialize this operation to JSON.

Captures the operation as a {"class", "params"} envelope: params is model_dump(mode="json") (every declared field, including nested operations and raw arrays; PrivateAttr state such as loggers and timing is excluded automatically), and class records the concrete class name so from_json() can rebuild the right subclass. This mirrors ImagePipeline.to_json().

Parameters:

filepath (str | Path | None) – Optional path to write the JSON to. When None, the JSON string is returned instead. Accepts a str or Path.

Returns:

The JSON string when filepath is None, otherwise None.

Return type:

str | None

Example

>>> import tempfile
>>> from pathlib import Path
>>> from phenotypic.detect import OtsuDetector
>>> from phenotypic.sdk_ import CONFIG_SUFFIX_OPERATION, ensure_typed_json_suffix
>>> with tempfile.TemporaryDirectory() as d:
...     p = Path(d) / "op.json"
...     saved = ensure_typed_json_suffix(p, CONFIG_SUFFIX_OPERATION)
...     OtsuDetector(ignore_zeros=True).to_json(p)
...     loaded = OtsuDetector.from_json(saved)
>>> loaded.ignore_zeros
True
widget(image: Image | None = None, show: bool = False) Widget

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.

clip: bool
convert2ycbcr: bool
gat_gain: float
gat_mu: Annotated[float, TuneSpec(tunable=False)]
gat_read_sigma: float
gat_scale_factor: float | None
mode: Literal['soft', 'hard']
model_computed_fields = {}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'validate_assignment': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property model_extra: dict[str, Any] | None

Get extra fields set during validation.

Returns:

A dictionary of extra fields, or None if config.extra is not set to “allow”.

model_fields = {'clip': FieldInfo(annotation=bool, required=False, default=True, description='Clamp gray and detect_mat outputs to [0, 1] after denoising. Soft thresholding can produce marginally negative values near dark colony edges; clipping eliminates these. Automatically deferred to ``False`` inside the GAT region so the inverse transform operates on the full stabilized signal before the final clamp. Default: ``True``. # GAT parameters (active only when use_gat=True)'), 'convert2ycbcr': FieldInfo(annotation=bool, required=False, default=True, description='Convert RGB to YCbCr before denoising so luminance and chrominance channels are thresholded independently, preserving colony hue for pigmentation assays. Applies only when RGB data is present. Default: ``True``.'), 'gat_gain': FieldInfo(annotation=float, required=False, default=1.0, description='Camera gain in electrons per ADU. Typical range: 0.5--10 e-/ADU depending on sensor. Obtain from the manufacturer datasheet or a mean-variance calibration. Default: ``1.0``.', metadata=[Gt(gt=0)]), 'gat_mu': FieldInfo(annotation=float, required=False, default=0.0, description='Read-noise mean (dark-current baseline offset) in count units consistent with ``gat_scale_factor``. Set to 0.0 when the image has been bias-subtracted, covering most flatbed-scanner workflows.', metadata=[TuneSpec(low=None, high=None, step=None, log=False, categories=None, tunable=False)]), 'gat_read_sigma': FieldInfo(annotation=float, required=False, default=0.0, description='Read-noise standard deviation in count units consistent with ``gat_scale_factor``. Zero assumes pure Poisson noise; supplying the sensor read-noise spec (a few to a few tens of counts for typical scientific CCDs) improves stabilization at low signal levels. Default: ``0.0``.', metadata=[Ge(ge=0)]), 'gat_scale_factor': FieldInfo(annotation=Union[float, NoneType], required=False, default=None, description='Multiplier converting normalized [0, 1] float data to photon counts before the forward GAT. ``None`` auto-detects from image bit depth (8-bit: 255, 16-bit: 65535). Override for non-standard bit depths such as 12-bit sensors stored in a 16-bit container (4095). Default: ``None``.', metadata=[Gt(gt=0)]), 'mode': FieldInfo(annotation=Literal['soft', 'hard'], required=False, default='soft', description="Wavelet coefficient thresholding mode. ``'soft'`` shrinks surviving coefficients toward zero, producing smoother output preferred for detection preprocessing. ``'hard'`` zeroes coefficients below the threshold and leaves the rest unchanged, retaining sharper edges but introducing discontinuities that can appear as ringing near sharp boundaries. Default: ``'soft'``."), 'rescale_sigma': FieldInfo(annotation=bool, required=False, default=True, description='Allow skimage to internally rescale sigma when converting between dtypes. Automatically deferred to ``False`` during the gray and detect_mat passes when ``use_gat=True`` to prevent double-scaling the stabilized-domain noise level. Default: ``True``.'), 'sigma': FieldInfo(annotation=Union[float, NoneType], required=False, default=None, description='Noise standard deviation on the [0, 1] intensity scale. ``None`` auto-estimates from the median absolute deviation of the finest wavelet detail subband (MAD / 0.6745). The universal threshold T = sigma * sqrt(2 * log(N)) is conservative; reducing sigma by factors of 2--4 below the auto-estimate gives sharper output. Internally retargeted to 1.0 for gray and detect_mat when ``use_gat=True``; RGB is not GAT-wrapped. Default: ``None``.', metadata=[TuneSpec(low=0.01, high=0.1, step=None, log=True, categories=None, tunable=True)]), 'use_gat': FieldInfo(annotation=bool, required=False, default=False, description='Wrap gray and detect_mat denoising in the Generalized Anscombe Transform, converting Poisson-Gaussian noise into approximately unit-variance Gaussian noise so the VisuShrink threshold is correctly scaled across intensity levels. RGB is not transformed. Enable for fluorescence plate readers or low-light incubator images. Default: ``False``.'), 'wavelet': FieldInfo(annotation=str, required=False, default='db2', description="PyWavelets wavelet family name. ``'db2'`` is general-purpose with compact support; ``'db4'`` has more vanishing moments and wider support, representing smooth colony interiors more sparsely."), 'wavelet_levels': FieldInfo(annotation=Union[int, NoneType], required=False, default=None, description='Number of wavelet decomposition levels. ``None`` uses the library heuristic (maximum possible minus three). Practical manual range: 2--6. More levels suppress noise at coarser spatial scales; fewer levels restrict denoising to fine-grained noise.', metadata=[TuneSpec(low=2, high=6, step=None, log=False, categories=None, tunable=True)])}
property model_fields_set: set[str]

Returns the set of fields that have been explicitly set on this model instance.

Returns:

A set of strings representing the fields that have been set,

i.e. that were not filled from defaults.

rescale_sigma: bool
sigma: Annotated[float | None, TuneSpec(0.01, 0.1, log=True)]
use_gat: bool
wavelet: str
wavelet_levels: Annotated[int | None, TuneSpec(2, 6)]