The _operate() Contract#
Every PhenoTypic operation implements a single method: _operate(). This
page specifies the full contract that implementations must follow.
Signature#
def _operate(self, image: Image) -> Image:
Rules#
Return the image. Always return the
imageargument, even if you modified it in place. The pipeline relies on the return value.Access data through accessors. Use
image.detect_mat[:],image.objmask[:], etc. Do not access internal_dataattributes directly.Respect the read/write contract. Each ABC type specifies which accessors it may read and write. An enhancer that writes to
objmapis violating its contract.Store parameters on
self. The constructor should assign all configuration to instance attributes. The_operate()method accesses them viaself.param_name.Be deterministic. Given the same image and parameters, the operation should produce the same result. Use fixed random seeds if randomness is involved.
Preserve GridImage type. If the input is a
GridImage, the output must also be aGridImagewith grid state preserved. The base class handles this automatically when you return the sameimageobject.
Common Patterns#
Read-Transform-Write (Enhancer)#
def _operate(self, image):
mat = image.detect_mat[:]
transformed = some_function(mat, self.param)
image.detect_mat[:] = transformed
return image
Detect-Label-Write (Detector)#
def _operate(self, image):
mat = image.detect_mat[:]
mask = mat > self.threshold
labeled = label(mask).astype(np.uint16)
image.objmask[:] = mask
image.objmap[:] = labeled
return image
Read-Measure-Return (Measurement)#
def _operate(self, image):
objmap = image.objmap[:]
rows = []
for prop in regionprops(objmap):
rows.append({"ObjectLabel": prop.label, "MyMetric": ...})
return pd.DataFrame(rows)