phenotypic.abc_.PrefabPipeline#
- class phenotypic.abc_.PrefabPipeline(ops: List[ImageOperation] | Dict[str, ImageOperation] | None = None, meas: List[MeasureFeatures] | Dict[str, MeasureFeatures] | None = None, benchmark: bool = False, verbose: bool = False)[source]#
Bases:
ImagePipelineMarker class for pre-built, validated image processing pipelines from the PhenoTypic team.
PrefabPipeline is a specialized subclass of ImagePipeline that distinguishes “official” pre-built pipelines maintained by the PhenoTypic development team from user-created custom pipelines. It serves as a marker class (no additional functionality) that signals “this pipeline is validated, documented, and recommended for specific use cases in microbe colony phenotyping.”
What is PrefabPipeline?
PrefabPipeline is NOT an operation ABC and does NOT inherit from BaseOperation. Instead, it’s a subclass of ImagePipeline that:
Is a marker class: Inherits all ImagePipeline functionality unchanged; no new methods.
Indicates official status: Subclasses of PrefabPipeline are pre-built, validated pipelines with documented performance, parameter settings, and recommended use cases.
Enables classification: Code can distinguish official pipelines (
isinstance(obj, PrefabPipeline)) from user-defined pipelines for documentation, discovery, or defaulting.Provides templates: Each PrefabPipeline subclass is a complete processing workflow (enhancement, detection, refinement, measurement) ready to use out-of-the-box.
Available PrefabPipeline Subclasses
The PhenoTypic team maintains several pre-built pipelines optimized for different imaging scenarios:
HeavyOtsuPipeline: Multi-layer Otsu detection with aggressive refinement and measurement. - Use case: Robust colony detection on challenging images (uneven lighting, varied sizes). - Cost: Computationally expensive; best for offline batch processing. - Includes: Gaussian blur, CLAHE, Sobel filter, Otsu detection, morphological refinement,
grid alignment, multiple measurements.
HeavyWatershedPipeline: Watershed segmentation with extensive cleanup. - Use case: Closely-spaced, touching, or merged colonies. - Cost: Very expensive; suitable for small batches or deep analysis. - Includes: Enhancement, watershed detection, refinement, grid alignment, measurements.
RoundPeaksPipeline: Peak detection for well-separated, circular colonies. - Use case: Early-time-point growth, sparse or isolated colonies. - Cost: Fast; good for high-throughput screening. - Includes: Gaussian blur, round peak detection, size filtering, measurements.
GridSectionPipeline: Per-well section extraction and analysis. - Use case: Fine-grained per-well quality control and segmentation. - Cost: Moderate; depends on grid resolution. - Includes: Grid-aware section extraction, per-well measurements.
When to use PrefabPipeline vs Custom ImagePipeline
Use PrefabPipeline if: - You’re analyzing colony growth on agar plates (the intended use case). - You want an immediately usable, tested workflow without configuration. - You want to reproduce results matching published benchmarks or team documentation. - You need a baseline for custom extensions (subclass or copy and modify).
Create a custom ImagePipeline if: - Your imaging scenario is novel (unusual plate format, different organisms, special preparation). - You want to experiment with different detector/refiner/measurement combinations. - You have labeled ground truth and want to optimize parameters for your specific images. - You need pipeline extensions (custom operations not in standard library).
Using a PrefabPipeline
PrefabPipeline subclasses are used exactly like ImagePipeline:
from phenotypic import Image, GridImage from phenotypic.prefab import HeavyOtsuPipeline # Load image(s) image = GridImage.from_image_path('plate.jpg', nrows=8, ncols=12) # Instantiate and apply pipeline pipeline = HeavyOtsuPipeline() result = pipeline.apply(image) # or .operate([image]) # Access results colonies = result.objects measurements = result.measurements print(f"Detected: {len(colonies)} colonies") print(f"Measurements shape: {measurements.shape}")
Customizing a PrefabPipeline
PrefabPipelines accept tunable parameters in
__init__()to adapt to your images without rebuilding the pipeline structure:from phenotypic.prefab import HeavyOtsuPipeline # Use defaults (recommended for most cases) pipeline1 = HeavyOtsuPipeline() # Tune for noisier images pipeline2 = HeavyOtsuPipeline( gaussian_sigma=7, # Stronger blur small_object_min_size=150, # More aggressive noise removal border_remover_size=2 # Remove more edge objects ) # Parameters are typically named after the algorithm or parameter they control. # See pipeline docstring for available parameters and typical values.
When Parameters Fail: Creating a Custom Pipeline
If PrefabPipeline parameter tuning doesn’t solve your problem:
Analyze failures: Which step fails (detection, refinement, measurement)?
Use
pipeline.benchmark=True, verbose=Trueto trace execution.Visually inspect intermediate results (detection masks, refined masks).
Create a custom pipeline:
from phenotypic import ImagePipeline from phenotypic.enhance import GaussianBlur, CLAHE from phenotypic.detect import CannyDetector # Different detector from phenotypic.refine import SmallObjectRemover, MaskFill from phenotypic.measure import MeasureShape, MeasureColor # Custom pipeline for your specific use case custom = ImagePipeline() custom.add(GaussianBlur(sigma=3)) custom.add(CLAHE()) custom.add(CannyDetector(sigma=1.5, low_threshold=0.1, high_threshold=0.4)) custom.add(SmallObjectRemover(min_size=100)) custom.add(MaskFill()) custom.add(MeasureShape()) custom.add(MeasureColor()) # Test and iterate result = custom.operate([image])
Share successful custom pipelines: If you develop a successful custom pipeline for a new imaging scenario, consider contributing it as a PrefabPipeline subclass to the project.
Extending PrefabPipeline
To create a new official PrefabPipeline subclass:
from phenotypic.abc_ import PrefabPipeline from phenotypic.enhance import GaussianBlur, CLAHE from phenotypic.detect import OtsuDetector from phenotypic.refine import SmallObjectRemover from phenotypic.measure import MeasureShape class MyCustomPrefabPipeline(PrefabPipeline): '''Brief description of when to use this pipeline.''' def __init__(self, param1: int = 100, param2: float = 1.5, benchmark: bool = False, verbose: bool = False): '''Initialize with tunable parameters.''' ops = [ GaussianBlur(sigma=param2), CLAHE(), OtsuDetector(), SmallObjectRemover(min_size=param1), ] meas = [MeasureShape()] super().__init__(ops=ops, meas=meas, benchmark=benchmark, verbose=verbose)
Notes
Is a marker, not an operation: PrefabPipeline does not inherit from BaseOperation. It’s a convenient subclass of ImagePipeline for classification and discovery.
Inheritance of ImagePipeline features: PrefabPipeline inherits all ImagePipeline functionality: sequential operation chaining, benchmarking, verbose logging, batch processing via
.operate(), and serialization via.to_yaml()/.from_yaml().Parameter tuning via __init__(): Most PrefabPipeline subclasses expose key algorithm parameters in
__init__()(e.g., detection threshold, smoothing sigma, refinement footprint). Adjust these for your specific images before scaling to large batches.Benchmarking for profiling: Set
benchmark=Truewhen instantiating to track execution time and memory usage per operation. Useful for identifying bottlenecks in large batch runs.Documentation and examples: Each PrefabPipeline subclass is documented with use cases, typical parameters, performance characteristics, and example code. Check the subclass docstring for guidance.
Not for operations: Use PrefabPipeline only for complete pipelines. For individual operations (detection, enhancement, measurement), use operation ABCs directly.
Examples
Quick start: Detect colonies with HeavyOtsuPipeline
from phenotypic import GridImage from phenotypic.prefab import HeavyOtsuPipeline # Load a 96-well plate image image = GridImage.from_image_path('agar_plate.jpg', nrows=8, ncols=12) # Use the pre-built, validated pipeline pipeline = HeavyOtsuPipeline() result = pipeline.apply(image) # Access results print(f"Detected {len(result.objects)} colonies") print(f"Measurements: {result.measurements.columns.tolist()}")
Batch processing multiple plates with a PrefabPipeline
from phenotypic import GridImage from phenotypic.prefab import HeavyOtsuPipeline import glob # Load multiple plate images image_paths = glob.glob('batch_*.jpg') images = [GridImage.from_image_path(p, nrows=8, ncols=12) for p in image_paths] # Create pipeline (reusable for all images) pipeline = HeavyOtsuPipeline(benchmark=True) # Batch process results = pipeline.operate(images) # Collect results for i, result in enumerate(results): print(f"Image {i}: {len(result.objects)} colonies") print(f"Measurements shape: {result.measurements.shape}")
Customizing pipeline parameters for difficult images
from phenotypic import GridImage from phenotypic.prefab import HeavyOtsuPipeline image = GridImage.from_image_path('noisy_plate.jpg', nrows=8, ncols=12) # Increase smoothing and noise removal for difficult images pipeline = HeavyOtsuPipeline( gaussian_sigma=8, # Stronger blur small_object_min_size=200, # Aggressive noise removal border_remover_size=2 # More border filtering ) result = pipeline.apply(image) print(f"Robust detection: {len(result.objects)} colonies")
Comparing PrefabPipeline vs custom pipeline
from phenotypic import GridImage, ImagePipeline from phenotypic.prefab import HeavyOtsuPipeline from phenotypic.detect import CannyDetector from phenotypic.refine import SmallObjectRemover image = GridImage.from_image_path('plate.jpg', nrows=8, ncols=12) # Option 1: Use pre-built validated pipeline prefab = HeavyOtsuPipeline() result1 = prefab.apply(image) # Option 2: Create custom pipeline for comparison custom = ImagePipeline() from phenotypic.enhance import GaussianBlur custom.add(GaussianBlur(sigma=2)) custom.add(CannyDetector(sigma=1.5, low_threshold=0.1, high_threshold=0.4)) custom.add(SmallObjectRemover(min_size=100)) result2 = custom.apply(image) # Compare results print(f"Prefab: {len(result1.objects)}, Custom: {len(result2.objects)}")
Methods
This class represents a processing and measurement abc_ for Image operations and feature extraction.
The class provides an abc_ to process and apply a series of operations on an Image.
Applies processing to the given image and measures the results.
Returns a table of execution times for operations and measurements.
Drop references to the UI widgets.
Deserialize a pipeline from JSON format.
Measures properties of a given image and optionally includes metadata.
Sets the measurements to be used for further computation.
Sets the operations to be performed.
Push internal state into widgets.
Serialize the pipeline configuration to JSON format.
Return (and optionally display) the root widget.
- Parameters:
ops (List[ImageOperation] | Dict[str, ImageOperation] | None)
meas (List[MeasureFeatures] | Dict[str, MeasureFeatures] | None)
benchmark (bool)
verbose (bool)
- __del__()#
Automatically stop tracemalloc when the object is deleted.
- __getstate__()#
Prepare the object for pickling by disposing of any widgets.
This ensures that UI components (which may contain unpickleable objects like input functions or thread locks) are cleaned up before serialization.
Note
This method modifies the object state by calling dispose_widgets(). Any active widgets will be detached from the object.
- __init__(ops: List[ImageOperation] | Dict[str, ImageOperation] | None = None, meas: List[MeasureFeatures] | Dict[str, MeasureFeatures] | None = None, benchmark: bool = False, verbose: bool = False)#
This class represents a processing and measurement abc_ for Image operations and feature extraction. It initializes operational and measurement queues based on the provided dictionaries.
- Parameters:
ops (List[ImageOperation] | Dict[str, ImageOperation] | None) – A dictionary where the keys are operation names (strings) and the values are ImageOperation objects responsible for performing specific Image processing tasks.
meas (List[MeasureFeatures] | Dict[str, MeasureFeatures] | None) – An optional dictionary where the keys are feature names (strings) and the values are FeatureExtractor objects responsible for extracting specific features.
benchmark (bool) – A flag indicating whether to track execution times for operations and measurements. Defaults to False.
verbose (bool) – A flag indicating whether to print progress information when benchmark mode is on. Defaults to False.
- apply(image: Image, inplace: bool = False, reset: bool = True) GridImage | Image#
The class provides an abc_ to process and apply a series of operations on an Image. The operations are maintained in a queue and executed sequentially when applied to the given Image.
- Parameters:
image (Image) – The arr Image to be processed. The type Image refers to an instance of the Image object to which transformations are applied.
inplace (bool, optional) – A flag indicating whether to apply the transformations directly on the provided Image (True) or create a copy of the Image before performing transformations (False). Defaults to False.
reset (bool) – Whether to reset the image before applying the pipeline
- Return type:
- apply_and_measure(image: Image, inplace: bool = False, reset: bool = True, include_metadata: bool = True) pd.DataFrame#
Applies processing to the given image and measures the results.
This function first applies a processing method to the supplied image, adjusting it based on the given parameters. After processing, the resulting image is measured, and a DataFrame containing the measurement data is returned.
- Parameters:
image (Image) – The image to process and measure.
inplace (bool) – Whether to modify the original image directly or work on a copy. Default is False.
reset (bool) – Whether to reset any previous processing on the image before applying the current method. Default is True.
include_metadata (bool) – Whether to include metadata in the measurement results. Default is True.
- Returns:
A DataFrame containing measurement data for the processed image.
- Return type:
pd.DataFrame
- benchmark_results() pandas.DataFrame#
Returns a table of execution times for operations and measurements.
This method should be called after applying the pipeline on an image to get the execution times of the different processes.
- Returns:
A DataFrame containing execution times for each operation and measurement.
- Return type:
pd.DataFrame
- classmethod from_json(json_data: str | Path) SerializablePipeline#
Deserialize a pipeline from JSON format.
This method reconstructs a pipeline from a JSON string or file, restoring all operations, measurements, and configuration flags. Classes are imported from the phenotypic namespace and instantiated with their saved parameters.
- Parameters:
json_data (str | Path) – Either a JSON string or a path to a JSON file.
- Returns:
A new pipeline instance with the loaded configuration.
- Return type:
SerializablePipeline
- Raises:
ValueError – If the JSON is invalid or cannot be parsed.
ImportError – If a required operation or measurement class cannot be imported.
AttributeError – If a class cannot be found in the phenotypic namespace.
Example
Deserialize a pipeline from JSON format
>>> from phenotypic import ImagePipeline >>> >>> # Load from file >>> pipe = ImagePipeline.from_json('my_pipeline.json') >>> >>> # Load from string >>> json_str = '{"ops": {...}, "meas": {...}}' >>> pipe = ImagePipeline.from_json(json_str)
- measure(image: Image, include_metadata=True) pd.DataFrame#
Measures properties of a given image and optionally includes metadata. The method performs measurements using a set of predefined measurement operations. If benchmarking is enabled, the execution time of each measurement is recorded. When verbose mode is active, detailed logging of the measurement process is displayed. A progress bar is used to track progress if the tqdm library is available.
- Parameters:
- Returns:
- A DataFrame containing the results of all performed measurements combined
on the same index.
- Return type:
pd.DataFrame
- Raises:
Exception – An exception is raised if a measurement operation fails while being applied to the image.
- set_meas(measurements: List[MeasureFeatures] | Dict[str, MeasureFeatures])#
Sets the measurements to be used for further computation. The input can be either a list of MeasureFeatures objects or a dictionary with string keys and MeasureFeatures objects as values.
The method processes the given input to construct a dictionary mapping measurement names to MeasureFeatures instances. If a list is passed, unique class names of the MeasureFeatures instances in the list are used as keys.
- Parameters:
measurements (List[MeasureFeatures] | Dict[str, MeasureFeatures]) – A collection of measurement features either as a list of MeasureFeatures objects, where class names are used as keys for dictionary creation, or as a dictionary where keys are predefined strings and values are MeasureFeatures objects.
- Raises:
TypeError – If the measurements argument is neither a list nor a dictionary.
- set_ops(ops: List[ImageOperation] | Dict[str, ImageOperation])#
Sets the operations to be performed. The operations can be passed as either a list of ImageOperation instances or a dictionary mapping operation names to ImageOperation instances. This method ensures that each operation in the list has a unique name. Raises a TypeError if the input is neither a list nor a dictionary.
- Parameters:
ops (List[ImageOperation] | Dict[str, ImageOperation]) – A list of ImageOperation objects or a dictionary where keys are operation names and values are ImageOperation objects.
- Raises:
TypeError – If the input is not a list or a dictionary.
- to_json(filepath: str | Path | None = None) str#
Serialize the pipeline configuration to JSON format.
This method captures the pipeline’s operations, measurements, and configuration flags. It excludes internal state (attributes starting with ‘_’) and pandas DataFrames to keep the serialization clean and focused on reproducible configuration.
- Parameters:
filepath (str | Path | None) – Optional path to save the JSON. If None, returns JSON string. Can be a string or Path object.
- Returns:
JSON string representation of the pipeline configuration.
- Return type:
Example
Serialize a pipeline to JSON format
>>> from phenotypic import ImagePipeline >>> from phenotypic.detect import OtsuDetector >>> from phenotypic.measure import MeasureShape >>> >>> pipe = ImagePipeline(ops=[OtsuDetector()], meas=[MeasureShape()]) >>> json_str = pipe.to_json() >>> pipe.to_json('my_pipeline.json') # Save to file
- widget(image: Image | None = None, show: bool = False) Widget#
Return (and optionally display) the root widget.
- Parameters:
- Returns:
The root widget.
- Return type:
ipywidgets.Widget
- Raises:
ImportError – If ipywidgets or IPython are not installed.