Acquisition Metadata
Everything ScanImage® writes into a logged file comes from a property somewhere on hSI.
This page is the map between the two: what goes into the header, which API produces it, and
how to read it back.
See also
Output Files for the list of file types and ScanImage® BigTiff Specification for the byte-level layout. This page covers the API side.
The three metadata blocks
A ScanImage Tiff carries metadata in three places.
Block |
Produced by |
Contents |
|---|---|---|
Non-varying frame data |
|
The whole model state: every gettable property of |
ROI group data |
|
The serialized ROI group. Written once per file, pointed at by the |
Per-frame data |
|
The handful of values that change frame to frame. Written into each frame’s
|
str = hSI.getHeaderString(); % the non-varying block, as it appears in the file
str = hSI.getRoiDataString(); % the ROI block
The per-frame fields
These come straight off the StripeData for that frame, so if you are processing live you have the same values without parsing anything.
Header field |
StripeData property |
Meaning |
|---|---|---|
|
|
Frame number counted from the start of the acquisition mode. |
|
|
Which acquisition within the mode. |
|
|
Frame number within that acquisition. |
|
|
Seconds from |
|
|
Seconds to the acquisition start trigger. |
|
|
Seconds to the last next-file marker. |
|
|
Last frame of the acquisition. |
|
|
Last frame of the acquisition mode. |
|
(always written false) |
Reserved. |
|
|
Wall-clock time of the first pixel of the acquisition mode, as a date vector. |
Note
All the ..._sec values are relative to epoch, not to each other and not to
the file. To get absolute wall-clock time for a frame, add frameTimestamps_sec to
datenum(epoch).
Controlling what goes into the header
Property |
Effect |
|---|---|
|
Write the non-varying block and the per-frame block as JSON instead of the legacy
|
|
Cell array of extra model properties to include, named relative to |
|
Cell array of extra properties from outside the model. |
|
Declared per class, not set at run time. Lists properties each component keeps out of the header - device handles, transient state, log file names. |
hSI.useJsonHeaderFormat = true;
hSI.mdlCustomProps = {'hRoiManager.scanZoomFactor'};
The machinery underneath is most.Model’s mdlGetHeaderString and
mdlGetHeaderStruct - see The most Framework. getHeaderString rewrites the
scanimage.SI. prefix to SI., which is why header fields read as SI.hRoiManager....
Warning
Adding properties with expensive getters to mdlCustomProps costs time on
every file. Keep the list short.
Where the values come from
The header is a flat readout of the component model, so the mapping is direct. Some frequently used fields:
Header field |
Source |
|---|---|
|
|
|
Derived timing, RoiManager |
|
Field of view corner points, RoiManager |
|
|
|
Transit and flyback timing, Scan2D: Imaging Systems |
|
|
|
|
|
|
|
|
|
Derived from |
Reading it back
ScanImage ships readers for every file type it writes. They return the header as a struct
whose fields mirror the property paths above, so header.SI.hRoiManager.linePeriod in a
script is the same value as hSI.hRoiManager.linePeriod was at acquisition time.
Function |
Returns |
|---|---|
|
Header and image data from a Tiff. Omitting |
|
The fast path for whole volumes, with Python, MATLAB and Julia bindings. See ScanImage® TiffReader. |
|
|
|
The same data organized as a frame sequence rather than per ROI. |
|
The three ROI groups from the |
|
Arbitrary line scanning data. Accepts either the |
|
Photostimulation monitor records - x, y and beam power per sample. See Read Photostim Monitor File. |
|
Write modified image data back out carrying the original file’s metadata. Useful for producing cleaned-up motion correction reference images that ScanImage will still accept. |
Two helpers convert line scan data into more convenient forms:
scanimage.util.lineScan2Tiff(file) writes a Tiff, and
scanimage.util.lineScan2Kymo(file) produces a kymograph.
scanimage.util.lineScan2Img is an example script, not a function - open it to see how
a scanner set is rebuilt from a header, and adapt it.
% header only - does not read the image data
header = scanimage.util.opentif('experiment_00001.tif');
fprintf('%d x %d px, %.2f fps, zoom %g\n', ...
header.SI.hRoiManager.pixelsPerLine, ...
header.SI.hRoiManager.linesPerFrame, ...
header.SI.hRoiManager.scanFrameRate, ...
header.SI.hRoiManager.scanZoomFactor);
See also
ScannerSet and Scanner Models for rebuilding scan geometry from a header, and Recipes for a complete batch-processing example.