Micro-Manager can save files in two formats, which referred to as “separate image files” and “Image file stack”.
Separate image files
Acquired images are saved to disk as separate TIFF files, each containing a single grayscale image. The file naming convention is “img” prefix followed by frame number, channel name and slice number (img_00000000t_channel_00z.tif). In addition, the folder will contain a file named “metadata.txt” that contains the metadata in JSON format.
Image file stack (in brief)
A TIFF file or group of TIFF files that contain multiple acquired images per a single file. These files conform to the OME-TIFF specification, allowing them to be easily imported into a variety of analysis applications including anything that utilizes the Bio-Formats library.
Image file stacks are designed to be easily imported into ImageJ without the need for a special reader plugin. A stack file can be dragged onto the ImageJ toolbar and will automatically open as a hyperstack with the same contrast settings used in Micro-Manager. Any acquisition comments typed into the Multi-Dimensional Acquisition window or the comments tab of the main Micro-Manager GUI can be viewed by pressing “i” with one of these files open in ImageJ.
By default, one file is created for each XY stage position (up to a maximum of 4 GB per file). In the tools-options menu, this can be changed to save all XY positions in a single file. This is especially useful for acquisitions using a large number XY positions. Since OME-TIFFs require that an identical String of XML metadata be embedded in each file in an acquisition, acquisitions that have a large number of XY positions with a small amount of data at each one waste space on disk and time by writing the same String of metadata in each file at the acquisition’s conclusion.
Writing to these files results in faster performance than writing to Seperate Image Files, in part because it minizes the number of system calls to create new files. This can be advantageous in situations where disk write speed is a limiting factor (i.e. writing to a server or collecting data at a high rate).
Programming using Image file stacks
Existing Micro-Manager libraries can be used to easily read these files. in order to do so a java project must use MMCoreJ.jar and MMJ_.jar as libraries. These JARs can be found in the Micro-Manager-1.4/plugins/Micro-Manager/ directory. Both file formats sit behind a common interface for reading and writing, org/micromanager/api/TaggedImage.java. Image file stacks are implement by org/micromanager/acquisition/TaggedImageStorageMultipageTiff.java. To create an instance of this class, capable of reading an existing Image file stack data set, use:
TaggedImageStorageMultipageTiff stackReader = new TaggedImageStorageMultipageTiff("C:\\Data\\Directory where data set is", false, null, false, false);
Important methods for utilizing this class are:
public TaggedImage getImage(int channelIndex, int sliceIndex, int frameIndex, int positionIndex) public JSONObject getSummaryMetadata() public Set<String> imageKeys() public void close()
imageKeys() returns a
close() should be called to release the connection the files when they are no longer needed.
A TaggedImage simply consists of two public fields. TaggedImage.tags
is a reference to the image metadata, stored in a
JSONObject. TaggedImage.pix is a pointer to the
image pixels, stored in a
depending on the image type.
In addition to the
MMJ_.jar libraries that are
required for reading Image File Stacks, writing to these files requires
4 more libraries, which can also be found in
Writing images into the Image File Stack format uses the same class as reading one of these datasets, but requires a different parameters be passed to the constructor. When writing an Image File Stack, you will need to pass a JSONObject containing a minimal amount of summary metadata to the constructor. Code for creating this summary metadata with the minimal amount of tags needed for saving is listed below. In this example, a data set of 512x512 16 bit monochrome images is created with 10 time points, 8 z slices, 2 channels, and 3 positions.
summary = new JSONObject(); summary.put("Slices", 18; summary.put("Positions", 1); summary.put("Channels", 2); summary.put("Frames", 10); summary.put("Positions",3); summary.put("SlicesFirst",true); summary.put("TimeFirst",false); summary.put("PixelType", "GRAY16"); summary.put("Width",512); summary.put("Height",512); summary.put("Prefix","Put the desired base filename here"); //these are used to create display settings summary.put("ChColors", new org.json.JSONArray("[1,1]")); summary.put("ChNames", new org.json.JSONArray("["DAPI","FITC"]")); summary.put("ChMins", new org.json.JSONArray("[0,0]")); summary.put("ChMaxes", new org.json.JSONArray("[65535,65535]"));
TimeFirst tell the image storage what order to
expect images to arrive in. If the full complement of expected images
does not arrive by the time the image closes, but all images up to that
point have come in the expected order, the storage will automatically
complete the current frame with blank images (this behavior is useful
for correctly opening aborted acquisitions in ImageJ).
being true means a whole set of z slice images arrive before moving on
to another channel.
TimeFirst being false means all positions are
collected at a given time point before moving on to the next time point,
rather than running successive time lapses at each position.
Next, create the MultipageTiffWriter. The fourth argument is a boolean
specifying whether separate
metadata.txt files should also be
written (does not affect functionality, merely an easy extra way to view
metadata). The fifth argument is a boolean flag for whether XY positions
should be placed in separate files or combined into a single one. In
this case we don’t create
metadata.txt, and we create seperate files
for XY positions:
TaggedImageStorageMultipageTiff storage = new TaggedImageStorageMultipageTiff("C:/Data/Directory where you want to save",true,summary,false,true);
Important methods for writing images are:
public void putImage(TaggedImage taggedImage) public void finished() public void close()
finished() should be called after no more image are going to be
added. The storage becomes read only after this call
close() should be called after images are done being both read and
Image file stack specification
Micro-Manager Image file stacks conform to both the TIFF Specification and OME TIFF Specification, contain data allowing them to be easily imported into ImageJ, store acquisition comments and display settings, and store an index map of the byte offsets of images within a file to allow for optimal reading performance.
|Bytes 0-7 (0x0-0x7)||Standard TIFF Header|
|8-11 (0x8-0xb)||Index map offset header (54773648 = 0x0343C790)|
|12-15 (0xc-0xf)||Index map offset|
|16-19 (0x10-0x13)||Display settings offset header (483765892 = 0x1CD5AE84)|
|20-23 (0x14-0x17)||Display settings offset|
|24-27 (0x18-0x1b)||Comments offset header (99384722 = 0x05EC7D92)|
|28-31 (0x1c-0x1f)||Comments offset|
|32-35 (0x20-0x23)||Summary metadata header (2355492 = 0x0023F124)|
|36-39 (0x24-0x27)||Summary metadata length|
|40- (0x28-)||summary metadata (UTF-8 JSON)|
Image File Directories
The first IFD starts immediately after the summary metadata. Each IFD will contain the same set of TIFF tags, except for the first one in each file, which contains two ImageJ metadata tags, and two copies of the ImageDescription tag. One of these contains a string needed by ImageJ to recognize these files, and the other contains OME metadata. Although these tags appear in the first IFD, their values will not be written until the end of the file, when it is closed. The tags are written in the following order (non-standard TIFF tags have the values listed after them), following the TIFF specification requirement that they be sorted numerically:
ImageWidth (256 = 0x0100)
ImageHeight (257 = 0x0101)
BitsPerSample (258 = 0x0102)
Compression (259 = 0x0103)
PhotometricInterpretation (262 = 0x0106)
ImageDescription (270 = 0x010e) (first IFD only)–contains OME XML metadata
a 2nd ImageDescription (270 = 0x010e) (first IFD only)-–contains ImageJ file opening information
StripOffsets (273 = 0x0111)
SamplesPerPixel (277 = 0x0115)
RowsPerStrip (278 = 0x0116)
StripByteCounts (279 = 0x0117)
XResolution (282 = 0x011a)
YResolution (283 = 0x011b)
ResolutionUnit (296 = 0x0128)
IJMetadataByteCounts (first IFD only) (50838 = 0xc696)
IJMetadata (first IFD only) (50839 = 0xc697)
MicroManagerMetadata (51123 = 0xc7b3)
Immediately after these tags are written:
-4 bytes containg the offset of the next IFD (per the TIFF specification)
-The pixel data
-In RGB files only, 6 bytes containing the values of the BitsPerSample tag Pixel values
-16 bytes containing the values of the XResolution and YResolution tags
-The value of the MicroManagerMetadata tag: image metadata (UTF-8 JSON)
End of file
After the last IFD, the following constructs are written:
A listing of all the images contained in the file and their byte offsets. This allows a specific image to be quickly accessed without having to parse the entire file and read in image metadata. It consists of the following:
-A 4 byte header (3453623 = 0x0034b2b7)
-4 bytes containing the number of entries in the index map
-20 bytes for each entry, with 4 bytes each allocated to the image’s channel index, slice index, frame index, position index, and byte offset of the image’s IFD within the file
If for some reason a file fails to write out its index map (i.e. the application crashes during file writing), opening this file will present a dialog asking if you would like to “fix” the data set. This fixing process consists of reading through all the IFDs present in the file to reconstruct the index map and then writing it to the end of the file.
A subset of the metadata used by the ImageJ TIFF writer (ij.io.TiffEncoder.java), which allows contrast settings and acquisition comments to propagate into ImageJ. The position and size of this metadata is specified by the IJMetadataCounts and IJMetadata tags in the first IFD.
OME XML Metadata
A string containing the OME XML metadata for this data set. This String is referenced by the first of the two ImageDescription tags in the first IFD of the file, in accordance with the OME-TIFF specification. Since this String must be identical for all files in a data set, it is not written for any file until the entire data set is closed at the conclusion of an acquisition.
ImageJ Image Description String
The ImageJ image description String that allows these files to opened correctly as hyperstacks in ImageJ. This String is referenced by the second of the two ImageDescription tags in the first IFD of the file.
Image display settings
Image display settings (channel contrast and colors), which are automatically rewritten whenever these are changed in an open data set. The first 4 bytes of this block contain the Display Settings Header (347834724 = 0x14BB8964), and the next 4 contain the number of subsequent bytes reserved for display settings. A UTF-8 JSON string containing display settings is written.
Acquisition and Image comments
A String containing acquisition and Image comments. The first 4 bytes of this block contain the Comments Header (84720485 = 0x050CBB65), and the next 4 contain the length of the string to follow. The acquisition comments are written as a UTF-8 JSON string. This string is rewritten whenever acquisition or image comments are changed.
–Henry Pinkard 7:35, 20th March 2013 (PDT)