IOBlock example — a custom TIFF loader
LoadTiffImage (load_tiff_image.py) teaches the Load block to read a plain
.tif micrograph into this project's Image type. Loaders and savers are how
data gets in and out of a workflow — here, in.
The simple helpers
You almost never subclass IOBlock directly. Use the two helper bases from
scistudio.blocks.io:
SimpleLoader— reads a file → aDataObject. You implementload_file(self, path, config).SimpleSaver— writes aDataObject→ a file. You implementsave_file(self, obj, path, config).
A loader needs three class attributes plus the one method:
class LoadTiffImage(SimpleLoader):
output_type = Image # the type you produce
format_id = "tiff" # a short stable id for this format
extensions = (".tif", ".tiff") # the file extensions you claim
def load_file(self, path, config) -> Image:
...
That is all SciStudio needs to register your loader, route matching files to
it, and show it in the palette. The file path the user picks arrives as
path — read it from there.
What to notice
- A narrow contract, kept. The reader below handles exactly one TIFF flavor — single-page, uncompressed, 8-bit grayscale — and refuses everything else by name. A loader that guesses is a loader that corrupts data silently; the imaging package pattern is one narrow capability per format variant.
- The source travels. The loader records
FrameworkMeta(source=...)on the value. Everything downstream that names the data — preview cards, save dialogs — reads it. - Depends on the Image type.
from image import Imageresolves because a project'stypes/folder is on the import path. Copy types/image/ into your project first; with both files in place, a Load node pointed at a.tifproduces anImage.
Beyond the basics
SimpleLoader/SimpleSaver synthesise a conservative format capability
for you (which type, which direction, which extensions). When you need finer
control — several formats in one block, declaring exactly which metadata
survives the round-trip — declare format_capabilities and a
MetadataFidelity explicitly, or subclass IOBlock and override load() /
save(). See scistudio.blocks.io in the API reference (FormatCapability,
MetadataFidelity).
Try it
Put types/image/ in types/ and this block in blocks/,
reload blocks, then drop a Load node on the canvas and point it at a .tif.