API Reference
This document provides detailed API documentation for extending Granny with new analysis modules and interfaces.
Core Classes
Analysis Base Class
- class Analysis
Abstract base class for all analysis modules.
All custom analyses must inherit from this class and implement the abstract methods.
Location:
Granny/Analyses/Analysis.pyClass Attributes:
- __analysis_name__: str
Machine-readable name for the analysis. Used in CLI
--analysisargument.Example:
"segmentation","starch","blush"
Instance Attributes:
- in_params: Dict[str, Value]
Dictionary of input parameters. Keys are parameter names, values are Value objects.
- compatibility: Dict[str, Dict[str, str]]
Mapping of compatible analyses. Format:
{ "other_analysis_name": { "my_param": "their_return_value" } }
- metadata: List[Value]
List of metadata values automatically added to all analyses: -
dt- Analysis date/time -id- Unique analysis identifier (UUID) -path- Current directory path
Methods:
- __init__()
Initialize the analysis. Must call
super().__init__()first.Subclasses should: - Initialize instance variables - Define input parameters using Value objects - Set default values for parameters - Register parameters with
addInParam()
- addInParam(*params: Value) None
Add one or more input parameters to the analysis.
- Parameters
params (Value) – Variable number of Value objects to register
Example:
threshold = IntValue("th", "threshold", "Detection threshold") self.addInParam(threshold)
- getInParams() Dict[str, Value]
Get all input parameters.
- Returns
Dictionary of parameter names to Value objects
- Return type
Dict[str, Value]
- resetInParams() None
Clear all input parameters. Used when re-configuring an analysis instance.
- addRetValue(*values: Value) None
Add one or more return values that other analyses can use.
- Parameters
values (Value) – Variable number of Value objects
- getRetValues() Dict[str, Value]
Get all return values.
- Returns
Dictionary of return value names to Value objects
- Return type
Dict[str, Value]
- resetRetValues() None
Clear all return values.
- performAnalysis() List[Image]
Perform the analysis on input images. Do not override this method.
The default implementation: 1. Loads images from
input_imagesparameter viaImageListValue.readValue()2. Calls_preRun()for setup 3. Processes images in parallel usingmultiprocessing.Pool4. Calls_postRun()with results- Returns
List of processed Image objects (from
_postRun())- Return type
List[Image]
Abstract Methods (must implement):
- abstract _preRun() None
Setup before image processing begins. Called once before any images are processed.
Use this for: - Initializing result containers - Loading models or resources - Printing analysis parameters
- abstract _processImage(image: Image) Image
Process a single image. Runs in parallel across CPU cores.
- Parameters
image – Input Image instance
- Returns
Processed Image instance
- Return type
Important: This method runs in separate processes. Avoid modifying shared state.
- abstract _postRun(results: List[Image]) List[Image]
Post-processing after all images are done. Called once with all results.
Use this for: - Saving images to disk - Generating CSV reports - Computing aggregate statistics
- Parameters
results – List of processed Image objects from
_processImage()- Returns
Final list of result images
- Return type
List[Image]
GrannyUI Base Class
- class GrannyUI
Abstract base class for user interfaces.
Location:
Granny/Interfaces/UI/GrannyUI.pyConstructor:
- __init__(parser: ArgumentParser)
Initialize the interface.
- Parameters
parser (argparse.ArgumentParser) – ArgumentParser instance for command-line arguments
Instance Attributes:
- parser: ArgumentParser
The argparse ArgumentParser instance used for handling command-line arguments.
Abstract Methods:
- abstract run() None
ABSTRACT: Execute the interface.
This method is called to start the interface and must be implemented by all subclasses.
Typical implementation: 1. Parse command-line arguments 2. Get user input (CLI args, GUI forms, web requests, etc.) 3. Instantiate selected analysis 4. Set analysis parameters from user input 5. Call
analysis.performAnalysis()6. Handle/display results
Note:
addProgramArgs()is commonly implemented but not required by the base class. SeeGrannyCLIfor an example implementation.
Value Classes
All Value classes inherit from the abstract Value base class and provide type-safe parameter handling.
Location: Granny/Models/Values/
Value Base Class
- class Value
Abstract base class for all parameter value types.
Location:
Granny/Models/Values/Value.pyConstructor:
- __init__(name: str, label: str, help: str)
- Parameters
name – Machine-readable parameter name
label – Human-readable label (used for CLI arguments)
help – Help text describing the parameter
Attributes:
- name: str
Machine-readable name for the value.
- label: str
Human-readable label. Becomes CLI argument:
--{label}
- help: str
Help text displayed to users.
- type: Type
Python type of the value (int, float, str, etc.).
- value: Any
The current value.
- is_set: bool
Whether the user has set this value.
Methods:
- abstract validate(value: Any) bool
Validate that the value meets constraints. Must be implemented by subclasses.
- getName() str
Get the machine-readable name.
- getLabel() str
Get the human-readable label (used for CLI args).
- getHelp() str
Get the help text.
- getType() Type
Get the Python type of this value.
- setType(type: Type) None
Set the Python type.
- setValue(value: Any) None
Set the value. Calls
validate()first.
- getValue() Any
Get the current value.
- isSet() bool
Check if the user has set this value.
- setIsRequired(is_required: bool) None
Set whether this parameter is required.
- getIsRequired() bool
Check if this parameter is required.
IntValue
- class IntValue(Value)
Integer parameter type with min/max constraints.
Location:
Granny/Models/Values/IntValue.pyAdditional Methods:
- setMin(min_val: int) None
Set minimum allowed value.
- getMin() int
Get minimum allowed value.
- setMax(max_val: int) None
Set maximum allowed value.
- getMax() int
Get maximum allowed value.
Example:
threshold = IntValue("th", "threshold", "Detection threshold (0-255)") threshold.setMin(0) threshold.setMax(255) threshold.setValue(128) threshold.setIsRequired(False)
FloatValue
- class FloatValue(Value)
Floating-point parameter type with min/max constraints.
Location:
Granny/Models/Values/FloatValue.pyAdditional Methods:
- setMin(min_val: float) None
Set minimum allowed value.
- getMin() float
Get minimum allowed value.
- setMax(max_val: float) None
Set maximum allowed value.
- getMax() float
Get maximum allowed value.
Example:
alpha = FloatValue("alpha", "mask_alpha", "Mask transparency (0.0-1.0)") alpha.setMin(0.0) alpha.setMax(1.0) alpha.setValue(0.5)
StringValue
- class StringValue(Value)
String parameter type.
Location:
Granny/Models/Values/StringValue.pyExample:
model = StringValue("model", "model", "Model name or path") model.setValue("pome_fruit-v1_0")
BoolValue
- class BoolValue(Value)
Boolean flag parameter type.
Location:
Granny/Models/Values/BoolValue.pyExample:
debug = BoolValue("debug", "debug", "Enable debug mode") debug.setValue(False)
FileNameValue
- class FileNameValue(Value)
File path parameter type. Validates that path is a file or a valid model name.
Location:
Granny/Models/Values/FileNameValue.pyExample:
input_file = FileNameValue("input", "input_file", "Path to input file") input_file.setValue("/path/to/file.jpg")
FileDirValue
- class FileDirValue(Value)
Directory path parameter type. Creates directory if it doesn’t exist.
Location:
Granny/Models/Values/FileDirValue.pyExample:
output = FileDirValue("out", "output", "Output directory") output.setValue("./results/analysis") # Directory will be created
ImageListValue
- class ImageListValue(FileDirValue)
Image list/directory parameter type. Represents a directory containing images. Handles loading and saving of image lists.
Location:
Granny/Models/Values/ImageListValue.pyAdditional Methods:
- readValue() None
Load all images from the directory into the internal image list. Called automatically by
Analysis.performAnalysis().
- writeValue() None
Save all images in the internal list to the directory.
Example:
input_images = ImageListValue( "input", "input", "Directory containing input images" ) input_images.setIsRequired(True) input_images.setValue("./demo/images") # After readValue() is called: images = input_images.getImageList()
MetaDataValue
- class MetaDataValue(Value)
Metadata storage parameter type. Used for results directories and metadata.
Location:
Granny/Models/Values/MetaDataValue.pyExample:
results = MetaDataValue( "results", "results", "Results output directory" ) results.setValue("./results/analysis_2024-01-01")
Image Classes
Image Base Class
- class Image
Abstract base class for images in Granny.
Location:
Granny/Models/Images/Image.pyConstructor:
- __init__(filepath: str)
Initialize the Image with a file path.
- Parameters
filepath – Path to the image file
Attributes:
- filepath: str
Absolute file path of the image.
- image: NDArray[np.uint8]
The image data as a NumPy array.
- results: Any
Segmentation results (for use with YOLO models).
Methods:
- addValue(*values: Value) None
Add metadata values to the image.
- Parameters
values – One or more Value objects to attach
Example:
score = FloatValue("score", "score", "Analysis score") score.setValue(95.5) image.addValue(score)
- getValue(key: str) Value
Get a metadata value by name.
- Parameters
key – The name of the metadata value
- Returns
The Value object
- getFilePath() str
Get the absolute file path.
- getImageName() str
Get the filename (without path).
- getShape() tuple
Get the image dimensions (height, width, channels).
Abstract Methods:
- abstract getImage() NDArray[np.uint8]
Get the image data as a NumPy array.
- abstract setImage(image: NDArray[np.uint8]) None
Set the image data from a NumPy array.
RGBImage
- class RGBImage(Image)
RGB color image type. The most common image type used in Granny analyses.
Location:
Granny/Models/Images/RGBImage.pyConstructor:
- __init__(filepath: str)
Initialize with a file path.
- Parameters
filepath – Path to the image file
Additional Methods:
- toRGB() None
Convert image from BGR to RGB format.
- toBGR() None
Convert image from RGB to BGR format.
- rotateImage() None
Rotate the image 90 degrees clockwise.
Example:
# Load an image image = RGBImage("/path/to/image.jpg") image_io = RGBImageFile() image_io.setFilePath(image.getFilePath()) image.loadImage(image_io) # Process the image img_array = image.getImage() processed = cv2.cvtColor(img_array, cv2.COLOR_BGR2GRAY) image.setImage(processed) # Add metadata score = FloatValue("score", "score", "Analysis score") score.setValue(95.5) image.addValue(score) # Save image.saveImage(image_io, "./output")
ImageIO Classes
ImageIO Base Class
- class ImageIO
Abstract base class for image file handlers. Handles loading and saving individual images.
Location:
Granny/Models/IO/ImageIO.pyAttributes:
- filepath: str
Full path to the image file.
- image_dir: str
Directory containing the image.
- image_name: str
Filename of the image.
Methods:
- setFilePath(filepath: str) None
Set the file path and extract directory/filename.
- Parameters
filepath – Full path to the image file
Abstract Methods:
- abstract loadImage() NDArray[np.uint8]
Load and return the image data.
- abstract saveImage(image: NDArray[np.uint8], output_path: str) None
Save the image to the specified directory.
- abstract getType() str
Get the image type (e.g., “rgb”, “gray”).
RGBImageFile
- class RGBImageFile(ImageIO)
RGB image file handler. Uses OpenCV for loading/saving.
Location:
Granny/Models/IO/RGBImageFile.pyImages are loaded/saved in BGR format (OpenCV convention).
Example:
from Granny.Models.IO.RGBImageFile import RGBImageFile # Load an image image_io = RGBImageFile() image_io.setFilePath("/path/to/image.jpg") img_array = image_io.loadImage() # Returns NDArray in BGR format # Save an image image_io.saveImage(img_array, "/output/directory")
Scheduler Class
- class Scheduler
Manages dependencies between analyses and executes them in correct order.
Location:
Granny/Interfaces/Scheduler/Scheduler.pyUses a directed acyclic graph (DAG) with topological sorting to handle analysis dependencies.
Methods:
- __init__()
Initialize the scheduler.
- add_analysis(analysis: Analysis, dependencies: List[Analysis]) None
Add an analysis with its dependencies.
- Parameters
analysis – Analysis to add
dependencies – List of Analysis objects this analysis depends on
Example:
scheduler = Scheduler() segmentation = Segmentation() starch = StarchArea() scheduler.add_analysis(segmentation, []) scheduler.add_analysis(starch, [segmentation])
- schedule() List[int]
Determine execution order based on dependencies.
- Returns
List of analysis IDs in the order they should be run
- Raises
ValueError – If there is a cycle in the dependencies
- run() None
Execute all analyses in dependency order.
Calls
schedule()internally, then runs each analysis viaperformAnalysis().
Utility Functions
Analysis Discovery
To discover all available analyses:
from Granny.Analyses.Analysis import Analysis
# Get all analysis classes
analyses = Analysis.__subclasses__()
# Get analysis by name
for cls in analyses:
if cls.__analysis_name__ == "segmentation":
analysis = cls()
break
Parameter Introspection
To inspect parameters of an analysis:
analysis = StarchArea()
params = analysis.getInParams()
for param_name, param_obj in params.items():
print(f"Parameter: {param_obj.getLabel()}")
print(f" Type: {param_obj.getType()}")
print(f" Default: {param_obj.getValue()}")
print(f" Required: {param_obj.getIsRequired()}")
print(f" Help: {param_obj.getHelp()}")
if hasattr(param_obj, 'getMin'):
print(f" Range: {param_obj.getMin()} - {param_obj.getMax()}")
Common Patterns
Loading and Processing Images
from Granny.Models.Images.RGBImage import RGBImage
from Granny.Models.IO.RGBImageFile import RGBImageFile
# In _processImage():
def _processImage(self, image: Image) -> Image:
# Load image data
image_io = RGBImageFile()
image_io.setFilePath(image.getFilePath())
image.loadImage(image_io)
# Get NumPy array (BGR format)
img_array = image.getImage()
# Process with OpenCV/NumPy
result = cv2.cvtColor(img_array, cv2.COLOR_BGR2GRAY)
# Update image
image.setImage(result)
return image
Saving Results in _postRun()
from Granny.Models.IO.RGBImageFile import RGBImageFile
def _postRun(self, results: List[Image]) -> List[Image]:
output_dir = self.output_images.getValue()
image_io = RGBImageFile()
for image in results:
image.saveImage(image_io, output_dir)
return results
Adding Metadata to Images
from Granny.Models.Values.StringValue import StringValue
from Granny.Models.Values.FloatValue import FloatValue
# Add metadata in _processImage()
score = FloatValue("score", "score", "Analysis score")
score.setValue(95.5)
image.addValue(score)
# Retrieve metadata in _postRun()
for image in results:
metadata = image.getMetaData()
if "score" in metadata:
score_value = metadata["score"].getValue()
Setting Analysis Parameters (in interfaces)
# Get parameters
params = analysis.getInParams()
# Clear and reset
analysis.resetInParams()
# Set each parameter
for param in params.values():
label = param.getLabel()
if label in user_values:
param.setValue(user_values[label])
# else: uses default value
analysis.addInParam(param)
Type Annotations
For better type checking, use these type hints:
from typing import List, Dict, Any, Optional
from numpy.typing import NDArray
from Granny.Models.Images.Image import Image
from Granny.Models.Values.Value import Value
def _processImage(self, image: Image) -> Image:
...
def _postRun(self, results: List[Image]) -> List[Image]:
...
def getInParams(self) -> Dict[str, Value]:
...
def process_array(self, img: NDArray) -> NDArray:
...
See Also
Adding a New Analysis Module - Step-by-step guide for creating analyses
Adding a New Interface - Step-by-step guide for creating interfaces
Complete Example Analysis - Complete working example