phenotypic.sweep package#
Parameter sweep manifest generation for pipeline configurations.
This module provides a clean API for generating cartesian-product parameter
sweeps from ImagePipeline operations using a
Sweep + generate_sweep_manifest interface.
Public API:
Sweep— declare an operation and its swept/fixed parameters.Presence— likeSweep, but also tests omitting the operation.Fixed— explicitly mark a value as fixed (escape hatch for tuples).generate_sweep_manifest()— build manifest of all pipeline combinations.load_sweep_manifest()— reload pipelines from a saved manifest JSON.load_single_pipeline_from_manifest()— extract one pipeline’s JSON without deserializing all pipelines (used by SLURM workers).load_pipeline_names_from_manifest()— list pipeline names without deserializing any pipelines.
Example
>>> from phenotypic.sweep import Sweep, generate_sweep_manifest
>>> from phenotypic.enhance import GaussianBlur
>>> from phenotypic.detect import OtsuDetector
>>> config = [
... Sweep(GaussianBlur, sigma=(1.0, 2.0), truncate=4.0),
... Sweep(OtsuDetector, ignore_zeros=(True, False)),
... ]
>>> manifest = generate_sweep_manifest(config)
>>> manifest['total_pipelines']
4
- class phenotypic.sweep.Fixed(value: Any)[source]#
Bases:
objectWrapper to explicitly mark a parameter value as fixed (not swept).
Use
Fixedwhen you need to pass a tuple as a literal fixed value rather than having it interpreted as a set of values to sweep over.- Parameters:
value (Any) – The parameter value to hold fixed.
Examples
>>> from phenotypic.sweep import Sweep, Fixed >>> from phenotypic.enhance import GaussianBlur >>> # Without Fixed, a tuple is swept: >>> Sweep(GaussianBlur, sigma=(1.0, 2.0)) # sweeps sigma over 1.0 and 2.0 >>> # With Fixed, the tuple is passed as-is: >>> Sweep(GaussianBlur, sigma=Fixed((1.0, 2.0))) # sigma = (1.0, 2.0)
- class phenotypic.sweep.Presence(operation_class_or_sweep: type | Sweep, **params: Any)[source]#
Bases:
SweepSweep that also tests the absence of the operation.
Behaves identically to
Sweepbut adds one extra combination where the operation is omitted entirely from the pipeline.Can be constructed in two ways:
Same signature as
Sweep— class + keyword params.Wrapping an existing
Sweepinstance (no extra params allowed).
- Parameters:
- Raises:
TypeError – If extra
**paramsare passed when wrapping aSweepinstance.
Examples
>>> from phenotypic.sweep import Sweep, Presence >>> from phenotypic.sweep import generate_sweep_manifest >>> from phenotypic.enhance import GaussianBlur >>> from phenotypic.detect import OtsuDetector >>> config = [ ... Presence(GaussianBlur, sigma=(1.0, 2.0)), ... Sweep(OtsuDetector), ... ] >>> manifest = generate_sweep_manifest(config) >>> manifest['total_pipelines'] 3 >>> # Wrapping an existing Sweep: >>> config2 = [ ... Presence(Sweep(GaussianBlur, sigma=(1.0, 2.0))), ... Sweep(OtsuDetector), ... ] >>> manifest2 = generate_sweep_manifest(config2) >>> manifest2['total_pipelines'] 3
- class phenotypic.sweep.Sweep(operation_class: type, **params: Any)[source]#
Bases:
objectSpecification for an operation in a parameter sweep.
Defines which operation class to instantiate and which parameters to vary (sweep) vs. hold constant (fix) across a cartesian product of combinations.
- Parameters:
operation_class (type) – The operation class (not an instance). Must be a class with an
__init__accepting the provided parameter names.**params (Any) –
Keyword arguments specifying parameter values.
Tuple values are swept (each element becomes one combination).
Scalar values (int, float, str, bool, None) are fixed.
List values are fixed (passed as-is, not swept).
``Fixed(value)`` explicitly marks any value as fixed.
- Raises:
TypeError – If
operation_classis an instance rather than a class.ValueError – If a parameter name does not exist in the operation class constructor.
Examples
>>> from phenotypic.sweep import Sweep, Fixed >>> from phenotypic.enhance import GaussianBlur >>> from phenotypic.detect import OtsuDetector >>> # Sweep sigma over 3 values, fix truncate >>> s = Sweep(GaussianBlur, sigma=(1.0, 1.5, 2.0), truncate=4.0) >>> s.sweep_params {'sigma': [1.0, 1.5, 2.0]} >>> s.fixed_params {'truncate': 4.0}
- phenotypic.sweep.generate_sweep_manifest(configs: List[Sweep] | Dict[str, List[Sweep]], *, meas: list | None = None, filepath: str | Path | None = None, desc: str | None = None) dict[source]#
Generate a parameter sweep manifest from Sweep configurations.
Creates all cartesian-product pipeline combinations for the given sweep specifications, serialises them as JSON-compatible dicts, and optionally writes the manifest to a file.
- Parameters:
configs (List[Sweep] | Dict[str, List[Sweep]]) – Either a single
List[Sweep](auto-named Pipeline) or aDict[str, List[Sweep]]mapping config names to sweep lists.meas (list | None) – Optional list of
MeasureFeaturesinstances to attach to every generated pipeline.filepath (str | Path | None) – If provided, write the manifest JSON to this path.
desc (str | None) – Optional human-readable description stored in the manifest.
- Returns:
A dict with the manifest structure:
{ "version": "0.13.0", "description": "...", "total_pipelines": 4, "configs": { "<name>": { "n_combinations": 2, "pipelines": {...} } } }
- Raises:
TypeError – If
configsis not a list or dict.TypeError – If a Sweep’s
operation_classis an instance.ValueError – If a Sweep references invalid parameter names.
- Return type:
Examples
>>> from phenotypic.sweep import Sweep, generate_sweep_manifest >>> from phenotypic.enhance import GaussianBlur >>> from phenotypic.detect import OtsuDetector >>> config = [ ... Sweep(GaussianBlur, sigma=(1.0, 2.0), truncate=4.0), ... Sweep(OtsuDetector, ignore_zeros=(True, False)), ... ] >>> manifest = generate_sweep_manifest(config) >>> manifest['total_pipelines'] 4
- phenotypic.sweep.load_pipeline_names_from_manifest(filepath: str | Path) List[str][source]#
Load all pipeline names from a manifest without deserializing pipelines.
- Parameters:
- Returns:
List of pipeline names.
- Raises:
FileNotFoundError – If manifest does not exist.
- Return type:
- phenotypic.sweep.load_single_pipeline_from_manifest(filepath: str | Path, pipeline_name: str) str[source]#
Load a single pipeline’s JSON string from a manifest without deserializing all pipelines.
- phenotypic.sweep.load_sweep_manifest(filepath: str | Path) Dict[str, Dict[str, Any]][source]#
Load a sweep manifest and reconstruct
ImagePipelineobjects.- Parameters:
filepath (str | Path) – Path to a JSON manifest file previously created by
generate_sweep_manifest().- Returns:
Nested dict
{config_name: {pipeline_name: ImagePipeline, ...}, ...}.- Raises:
FileNotFoundError – If filepath does not exist.
- Return type:
Examples
>>> from phenotypic.sweep import load_sweep_manifest >>> pipelines = load_sweep_manifest("sweep.json") >>> for cfg_name, pipes in pipelines.items(): ... for pipe_name, pipe in pipes.items(): ... print(pipe_name, [op.__class__.__name__ for op in pipe._ops.values()])