/** This macro opens a series of images using the metadata.txt file from a Micromanager dataset (MM v. 1.4 or 2.0). It currently only supports folders of simgle image files, rather than the preferred MM 2.0 multi-image TIFFs. Written 2025/05/20 by Jeff Hardin, Univ. of Wisconsin-Madison */ path = File.openDialog("Select a File"); //print("Path:", path); //open(path); // open the file dir = File.getDirectory(path); //print("Directory: " + dir); //Get the metadata file if it exists; single-image folders have a generic "metadata.txt" file //MM 1.4 doesn't save one for OME-tif-based datasets, whereas MM 2 creates a "named" //file with "...metadata.txt" in the name metadataFile = "metadata.txt"; fileList = getFileList(dir); omeData = false; for (i = 0; i < fileList.length; i++) { //print(fileList[i]); if (lastIndexOf(fileList[i], "ome.tif") >= 0) { //print("OME tif dataset detected! " + fileList[i]); omeName = fileList[i]; omeData = true; break; } } for (i = 0; i < fileList.length; i++) { if (lastIndexOf(fileList[i], "metadata.txt") >= 0) { //print("Metadata file found! " + fileList[i]); metadataFile = fileList[i]; break; } } textPath = dir + metadataFile; //print("Metadata text file: " + textPath); myPath = ""; if (File.exists(textPath)) {myPath = textPath;} //print("My path: ", myPath); focalPlanes = 1; if (myPath != "") { //Open the metadata file and parse it to get focal planes //MM 1.4 and 2.0 have different metadata structures, so we'll look for lines with // "Slices:" and "Channels:" infoString = File.openAsString(myPath); // open the file lines=split(infoString,"\n"); //print("Query string: " + "\"Slices" + "\"" + ":"); slicesLine = -1; channelsLine = -1; for (i = 0; i < lines.length; i++) { //print("Line : " + i); //print(lines[i]); if (lastIndexOf(lines[i],"\"Slices" + "\"" + ":") > 0) { //print("Slices line found! " + lines[i]); slicesLine = i; //print("Line number: " + slicesLine); break; } } for (i= 0; i < lines.length; i++) { if (lastIndexOf(lines[i],"\"Channels" + "\"" + ":") > 0) { //print("Channels line found! " + lines[i]); //print("Line number: " + i); channelsLineNumber = i; break; } } focalPlanesLine = lines[slicesLine]; //print("Focal planes line: ",focalPlanesLine); focalPlanesString= substring(focalPlanesLine,lastIndexOf(focalPlanesLine,":")+1,lastIndexOf(focalPlanesLine,",")); //print("Clipped focal planes: ", focalPlanesString); focalPlanes = parseInt(focalPlanesString); //print("Final focal planes: ", focalPlanes); channelsLine = lines[channelsLineNumber]; //print("Channels line: ",channelsLine); channelsString= substring(channelsLine,lastIndexOf(channelsLine,":")+1,lastIndexOf(channelsLine,",")); //print("Clipped channels: ", channelsString); channels = parseInt(channelsString); //print("Final channels: ", channels); //channels = 1; } else if (!omeData) //if no info file with the approporatie root can be found, and not OME tiff dataset; //ask for focal planes { Dialog.create("Enter focal planes"); Dialog.addNumber("Couldn't get focal planes. Focal planes: ", 1); Dialog.addNumber("Couldn't get channels. Channels: ", 1); Dialog.show(); focalPlanes = Dialog.getNumber(); channels = Dialog.getNumber(); if (focalPlanes < 1) {focalPlanes = 1;} if (channels < 1) {channels = 1;} } if (!omeData){ File.openSequence(dir, "virtual"); getDimensions(w, h, c, slices, frames); print("Channels: " + channels); print("Total images: " + slices); print("Focal planes: " + focalPlanes); timePoints = slices/focalPlanes/channels; print("Time points: " + timePoints); run("Stack to Hyperstack...","order=xyzct channels=" + channels + " slices=" + focalPlanes + " frames=" + timePoints + " display=Grayscale"); } else { //In Fiji, using the "Open..." menu option sends the file to BioFormats... //We want to curcumvent the dialog... //open(dir + omeName); run("Bio-Formats", "open=[" + dir + omeName + "] color_mode=Default rois_import=[ROI manager] view=Hyperstack stack_order=XYCZT use_virtual_stack"); getDimensions(w, h, c, slices, frames); print("Channels: " + c); print("Total images: " + c*slices*frames); print("Focal planes: " + slices); timePoints = frames; print("Time points: " + timePoints); }