A derived product is an array that a component computes from a
run and keeps next to the data it came from, such as a
median over a scan or a filtered copy of every frame. The device and its
service write the run's own data; a derived product is the one thing redsun
writes, through a Writer.
Write a derived product shows every
step.
A Writer takes two kinds of input, from two directions. Step through to see
them reach it:
What reaches a writer
The camera and its service write the frames. The writer gets the documents and the product from a component.
the runThe RunEngine emits the run's documents while the camera and its service write the frames.the camera's storeThe device and its service chose the format and the place, and wrote the frames there.framesdocumentsdocumentsthe productThe RunEngine emits the run's documents while the camera and its service write the frames.The device and its service chose the format and the place, and wrote the frames there.
The component receives the run's documents like any document callback, and computes its product from the frames as they arrive.
the runThe RunEngine emits the run's documents while the camera and its service write the frames.componenta document callbackThe component receives the run's documents like any callback, and computes its product from the frames as they arrive.the camera's storeThe device and its service chose the format and the place, and wrote the frames there.framesdocumentsdocumentsthe productThe RunEngine emits the run's documents while the camera and its service write the frames.The component receives the run's documents like any callback, and computes its product from the frames as they arrive.The device and its service chose the format and the place, and wrote the frames there.
the runThe RunEngine emits the run's documents while the camera and its service write the frames.componenta document callbackThe component receives the run's documents like any callback, and computes its product from the frames as they arrive.the camera's storeThe device and its service chose the format and the place, and wrote the frames there.framesdocumentsdocumentsthe productThe RunEngine emits the run's documents while the camera and its service write the frames.The component receives the run's documents like any callback, and computes its product from the frames as they arrive.The device and its service chose the format and the place, and wrote the frames there.
It forwards each document to the writer, which learns where the frames went and what shape they have.
the runThe RunEngine emits the run's documents while the camera and its service write the frames.componenta document callbackThe component receives the run's documents like any callback, and computes its product from the frames as they arrive.the camera's storeThe device and its service chose the format and the place, and wrote the frames there.WriterThe documents tell the writer where the frames went and what shape they have, which is everything it needs to lay out the product.framesdocumentsdocumentsthe productThe RunEngine emits the run's documents while the camera and its service write the frames.The component receives the run's documents like any callback, and computes its product from the frames as they arrive.The device and its service chose the format and the place, and wrote the frames there.The documents tell the writer where the frames went and what shape they have, which is everything it needs to lay out the product.
the runThe RunEngine emits the run's documents while the camera and its service write the frames.componenta document callbackThe component receives the run's documents like any callback, and computes its product from the frames as they arrive.the camera's storeThe device and its service chose the format and the place, and wrote the frames there.WriterThe documents tell the writer where the frames went and what shape they have, which is everything it needs to lay out the product.framesdocumentsdocumentsthe productThe RunEngine emits the run's documents while the camera and its service write the frames.The component receives the run's documents like any callback, and computes its product from the frames as they arrive.The device and its service chose the format and the place, and wrote the frames there.The documents tell the writer where the frames went and what shape they have, which is everything it needs to lay out the product.
The documents can't carry the product, so the component hands the data over too, with write, or with append frame by frame.
the runThe RunEngine emits the run's documents while the camera and its service write the frames.componenta document callbackThe documents can't carry the product, because the component computes it after the frames arrive. So the component hands the data over itself, with write, or with append frame by frame.the camera's storeThe device and its service chose the format and the place, and wrote the frames there.WriterThe documents tell the writer where the frames went and what shape they have, which is everything it needs to lay out the product.framesdocumentsdocuments,then the productthe productThe RunEngine emits the run's documents while the camera and its service write the frames.The documents can't carry the product, because the component computes it after the frames arrive. So the component hands the data over itself, with write, or with append frame by frame.The device and its service chose the format and the place, and wrote the frames there.The documents tell the writer where the frames went and what shape they have, which is everything it needs to lay out the product.
the runThe RunEngine emits the run's documents while the camera and its service write the frames.componenta document callbackThe documents can't carry the product, because the component computes it after the frames arrive. So the component hands the data over itself, with write, or with append frame by frame.the camera's storeThe device and its service chose the format and the place, and wrote the frames there.WriterThe documents tell the writer where the frames went and what shape they have, which is everything it needs to lay out the product.framesdocumentsdocuments,then the productthe productThe RunEngine emits the run's documents while the camera and its service write the frames.The documents can't carry the product, because the component computes it after the frames arrive. So the component hands the data over itself, with write, or with append frame by frame.The device and its service chose the format and the place, and wrote the frames there.The documents tell the writer where the frames went and what shape they have, which is everything it needs to lay out the product.
The writer puts the product next to the frames, in the store the device chose.
the runThe RunEngine emits the run's documents while the camera and its service write the frames.componenta document callbackThe documents can't carry the product, because the component computes it after the frames arrive. So the component hands the data over itself, with write, or with append frame by frame.the camera's storeThe device and its service chose the format and the place, and wrote the frames there.WriterThe writer puts the product next to the frames, in the store the device chose.framesdocumentsdocuments,then the productthe productThe RunEngine emits the run's documents while the camera and its service write the frames.The documents can't carry the product, because the component computes it after the frames arrive. So the component hands the data over itself, with write, or with append frame by frame.The device and its service chose the format and the place, and wrote the frames there.The writer puts the product next to the frames, in the store the device chose.
the runThe RunEngine emits the run's documents while the camera and its service write the frames.componenta document callbackThe documents can't carry the product, because the component computes it after the frames arrive. So the component hands the data over itself, with write, or with append frame by frame.the camera's storeThe device and its service chose the format and the place, and wrote the frames there.WriterThe writer puts the product next to the frames, in the store the device chose.framesdocumentsdocuments,then the productthe productThe RunEngine emits the run's documents while the camera and its service write the frames.The documents can't carry the product, because the component computes it after the frames arrive. So the component hands the data over itself, with write, or with append frame by frame.The device and its service chose the format and the place, and wrote the frames there.The writer puts the product next to the frames, in the store the device chose.
Here is a component that keeps the median of a camera's frames, cut down to the
lines that talk to its writer:
self._median stands for what the component computed while the run went on;
a product written frame by frame goes in through append instead. The session
never subscribes a writer itself. The component forwards each document after
handling it, so the writer sees the run's stop only after the component has
written its result.
A product goes where its source data went, following the device's choice of
format and store
(ADR 0013).
derive("camera_median", source="camera") lays the median out like one camera
frame in the camera's store, and two documents of the run fill in the rest:
What derive takes from the run
derive names only the product and its source. Two documents of the run fill in the rest.
camera_medianderive(source="camera")descriptornaming cameraThe run's description of the stream the camera belongs to.stream_resourcenaming cameraThe document the device emits when it opens the file its frames go to.The run's description of the stream the camera belongs to.The document the device emits when it opens the file its frames go to.
camera_medianderive(source="camera")descriptornaming cameraThe run's description of the stream the camera belongs to.stream_resourcenaming cameraThe document the device emits when it opens the file its frames go to.The run's description of the stream the camera belongs to.The document the device emits when it opens the file its frames go to.
The descriptor gives the shape and dtype of the camera's key. derive drops its leading frames-per-event dimension, so the product is laid out like one frame.
camera_medianderive(source="camera")descriptornaming cameraThe run's description of the stream the camera belongs to.stream_resourcenaming cameraThe document the device emits when it opens the file its frames go to.the frame'sshape and dtypeA key the camera streams leads its shape with the frames per event, which derive drops.The run's description of the stream the camera belongs to.The document the device emits when it opens the file its frames go to.A key the camera streams leads its shape with the frames per event, which derive drops.
camera_medianderive(source="camera")descriptornaming cameraThe run's description of the stream the camera belongs to.stream_resourcenaming cameraThe document the device emits when it opens the file its frames go to.the frame'sshape and dtypeA key the camera streams leads its shape with the frames per event, which derive drops.The run's description of the stream the camera belongs to.The document the device emits when it opens the file its frames go to.A key the camera streams leads its shape with the frames per event, which derive drops.
The stream_resource gives the store's URI and format. The writer knows plain Zarr and OME-Zarr, and skips the product for any other format, logging it once.
camera_medianderive(source="camera")descriptornaming cameraThe run's description of the stream the camera belongs to.stream_resourcenaming cameraThe document the device emits when it opens the file its frames go to.the frame'sshape and dtypeA key the camera streams leads its shape with the frames per event, which derive drops.the store'sURI and formatThe format is the document's mimetype. The writer knows plain Zarr and OME-Zarr, and skips the product for a run whose store has another, logging it once.The run's description of the stream the camera belongs to.The document the device emits when it opens the file its frames go to.A key the camera streams leads its shape with the frames per event, which derive drops.The format is the document's mimetype. The writer knows plain Zarr and OME-Zarr, and skips the product for a run whose store has another, logging it once.
camera_medianderive(source="camera")descriptornaming cameraThe run's description of the stream the camera belongs to.stream_resourcenaming cameraThe document the device emits when it opens the file its frames go to.the frame'sshape and dtypeA key the camera streams leads its shape with the frames per event, which derive drops.the store'sURI and formatThe format is the document's mimetype. The writer knows plain Zarr and OME-Zarr, and skips the product for a run whose store has another, logging it once.The run's description of the stream the camera belongs to.The document the device emits when it opens the file its frames go to.A key the camera streams leads its shape with the frames per event, which derive drops.The format is the document's mimetype. The writer knows plain Zarr and OME-Zarr, and skips the product for a run whose store has another, logging it once.
For a product the run says nothing about, declare gives the shape, the type
and the store up front instead:
Both derive and declare belong in the constructor, before the run starts,
because the stores can't grow new arrays later. Step through a run to see when
each part happens:
A product over one run
derive and declare go in the constructor, before the run starts.
componentWriterthe camera's storederive, in the constructordocuments: start,descriptor, stream_resourcefirst append or writeopen the stream:size every arrayappend a product declaredsince: WriterErrordocuments: stopclose the stream,write the metadata
componentWriterthe camera's storederive, in the constructordocuments: start,descriptor, stream_resourcefirst append or writeopen the stream:size every arrayappend a product declaredsince: WriterErrordocuments: stopclose the stream,write the metadata
The component forwards the run's first documents. The writer learns each product's layout and store, but opens nothing yet.
componentWriterthe camera's storederive, in the constructordocuments: start,descriptor, stream_resourcefirst append or writeopen the stream:size every arrayappend a product declaredsince: WriterErrordocuments: stopclose the stream,write the metadata
componentWriterthe camera's storederive, in the constructordocuments: start,descriptor, stream_resourcefirst append or writeopen the stream:size every arrayappend a product declaredsince: WriterErrordocuments: stopclose the stream,write the metadata
The first append or write opens the store's stream with every product known by then. acquire-zarr sizes the arrays once, at this moment, and ome-writers allocates every frame of an image.
componentWriterthe camera's storederive, in the constructordocuments: start,descriptor, stream_resourcefirst append or writeopen the stream:size every arrayappend a product declaredsince: WriterErrordocuments: stopclose the stream,write the metadata
componentWriterthe camera's storederive, in the constructordocuments: start,descriptor, stream_resourcefirst append or writeopen the stream:size every arrayappend a product declaredsince: WriterErrordocuments: stopclose the stream,write the metadata
A product declared after the stream opened can't join it, so append raises WriterError.
componentWriterthe camera's storederive, in the constructordocuments: start,descriptor, stream_resourcefirst append or writeopen the stream:size every arrayappend a product declaredsince: WriterErrordocuments: stopclose the stream,write the metadata
componentWriterthe camera's storederive, in the constructordocuments: start,descriptor, stream_resourcefirst append or writeopen the stream:size every arrayappend a product declaredsince: WriterErrordocuments: stopclose the stream,write the metadata
At the run's stop document, the writer closes the stream and writes the metadata: the mapping given to write, and one naming the run, the source, the store and the time.
componentWriterthe camera's storederive, in the constructordocuments: start,descriptor, stream_resourcefirst append or writeopen the stream:size every arrayappend a product declaredsince: WriterErrordocuments: stopclose the stream,write the metadata
componentWriterthe camera's storederive, in the constructordocuments: start,descriptor, stream_resourcefirst append or writeopen the stream:size every arrayappend a product declaredsince: WriterErrordocuments: stopclose the stream,write the metadata
A product can't join a store whose stream is open. For the same reason, a
product that gets a store of its own, beside an OME-Zarr image, is written all
at once rather than frame by frame: write opens and finishes that store in
one call, and append to it is refused.