// Make Overlays Macro by Christophe Leterrier // 12-11-2015 macro "Make_Overlays" { // Get the folder name INPUT_DIR = getDirectory("Select a directory full of tif images"); print("\n\n\n*** Make_Overlays Log ***"); print("INPUT_DIR:" + INPUT_DIR); OUTPUT_NAME = File.getName(INPUT_DIR); // Count the number of files ending with ".tif" as the number of images ALL_NAMES = getFileList(INPUT_DIR); Array.sort(ALL_NAMES); IMAGE_NUMBER = 0; for (i = 0; i < ALL_NAMES.length; i++) { LENGTH = lengthOf(ALL_NAMES[i]); if (substring(ALL_NAMES[i],LENGTH-4,LENGTH) == ".tif") { IMAGE_NUMBER ++; } } print("IMAGE_NUMBER:" + IMAGE_NUMBER); // Array that stores the images names IMAGE_NAMES = newArray(IMAGE_NUMBER); for (i = 0; i < ALL_NAMES.length; i++) { LENGTH = lengthOf(ALL_NAMES[i]); if (substring(ALL_NAMES[i], LENGTH-4, LENGTH) == ".tif") { IMAGE_NAMES[i] = ALL_NAMES[i]; } } // Looks at the last three characters of the name (without extension) as the channel ID index = 1; FIRST_INDEX = substring(IMAGE_NAMES[0], lengthOf(IMAGE_NAMES[0]) - 7, lengthOf(IMAGE_NAMES[0]) - 4); CURRENT_INDEX = substring(IMAGE_NAMES[index], lengthOf(IMAGE_NAMES[index]) - 7, lengthOf(IMAGE_NAMES[index]) - 4); // iterates a counter until it finds the same channel ID as the first image file, deducing the channels count while (FIRST_INDEX != CURRENT_INDEX) { index++; CURRENT_INDEX = substring(IMAGE_NAMES[index], lengthOf(IMAGE_NAMES[index]) - 7, lengthOf(IMAGE_NAMES[index]) - 4); } CHANNEL_COUNT = index; print("CHANNEL_COUNT:" + CHANNEL_COUNT); // As the Merge command does not take more than 6 channels, the macro will exit if there are more if (CHANNEL_COUNT > 6) { exit("Can't deal with more than 6 channels!"); } //Store the channels IDs CHANNEL_NAMES=newArray(CHANNEL_COUNT); for (i = 0; i < CHANNEL_COUNT; i++) { CHANNEL_NAMES[i]=substring(IMAGE_NAMES[i],lengthOf(IMAGE_NAMES[i])-7,lengthOf(IMAGE_NAMES[i])-4); } // Define default colors depending on the number of channels DEF_COLORS = newArray(CHANNEL_COUNT); if (CHANNEL_COUNT == 1){ DEF_COLORS[0] = "Grays"; } else if (CHANNEL_COUNT == 2) { DEF_COLORS[0] = "Red"; DEF_COLORS[1] = "Green"; } else if (CHANNEL_COUNT == 3) { DEF_COLORS[0] = "Blue"; DEF_COLORS[1] = "Red"; DEF_COLORS[2] = "Green"; } else if (CHANNEL_COUNT == 4) { DEF_COLORS[0] = "Blue"; DEF_COLORS[1] = "Red"; DEF_COLORS[2] = "Green"; DEF_COLORS[3] = "Gray"; } else { DEF_COLORS[0] = "Blue"; DEF_COLORS[1] = "Red"; DEF_COLORS[2] = "Green"; for (k = 3; k < CHANNEL_COUNT; k++) { DEF_COLORS[k] = "Grays"; } } FLAT_DEF = false; // Define the choice of colors and the array that will store the choices COLORS = newArray("None", "Red", "Green", "Blue", "Grays", "Cyan", "Magenta", "Yellow"); COLORS_CHOICE = newArray(CHANNEL_COUNT); // Create the dialog box Dialog.create("Make Overlays Parameters"); Dialog.addMessage("Total number of images: " + IMAGE_NUMBER); Dialog.addMessage("Number of Channels: " + CHANNEL_COUNT); // Each channel gets an entry, with a choice of colors for the overlay. All channels will be used in the Composite image for (k = 0; k < CHANNEL_COUNT; k++) { Dialog.addChoice("" + (k+1)+ "- Channel "+ CHANNEL_NAMES[k]+ ": ", COLORS, DEF_COLORS[k]); } Dialog.addCheckbox("Flatten to RGB", FLAT_DEF); Dialog.show(); // Feed the variables with the dialog values for (k = 0; k < CHANNEL_COUNT; k++) { COLORS_CHOICE[k] = Dialog.getChoice(); } FLAT = Dialog.getCheckbox(); // Create output directory and path PARENT_DIR = File.getParent(INPUT_DIR); OUTPUT_DIR = PARENT_DIR + File.separator + "Overlays" + File.separator; if (File.isDirectory(OUTPUT_DIR) == false) { File.makeDirectory(OUTPUT_DIR); } print("OUTPUT_DIR:" + OUTPUT_DIR); setBatchMode(true); // Generate the color code appended to the overlay file name COLOR_CODE = ""; COL_NUM = 0; for (k = 0; k < CHANNEL_COUNT; k++) { if (COLORS_CHOICE[k] == "None") letter = "n"; else if (COLORS_CHOICE[k] == "Red") { letter = "R"; COL_NUM++; } else if (COLORS_CHOICE[k] == "Green") { letter = "G"; COL_NUM++; } else if (COLORS_CHOICE[k] == "Blue") { letter = "B"; COL_NUM++; } else if (COLORS_CHOICE[k] == "Grays") { letter = "W"; COL_NUM++; } else if (COLORS_CHOICE[k] == "Cyan") { letter = "C"; COL_NUM++; } else if (COLORS_CHOICE[k] == "Magenta") { letter = "M"; COL_NUM++; } else if (COLORS_CHOICE[k] == "Yellow") { letter = "Y"; COL_NUM++; } COLOR_CODE += letter; } if (FLAT == true) COLOR_CODE += "f"; else COLOR_CODE += "c"; // Loop on all channels from all images for (i = 0; i < IMAGE_NUMBER - CHANNEL_COUNT + 1; i = i + CHANNEL_COUNT) { MERGE_STRING = ""; LABELS = newArray(COL_NUM); CurrCh = 0; for (k = 0; k < CHANNEL_COUNT; k++) { if (COLORS_CHOICE[k] == "None") { } else { open(INPUT_DIR + File.separator + IMAGE_NAMES[i + k]); LABELS[CurrCh] = IMAGE_NAMES[i + k]; MERGE_STRING += "c" + (k + 1) + "='" + IMAGE_NAMES[i + k] + "' "; CurrCh++; } } print(MERGE_STRING); run("Merge Channels...", MERGE_STRING +"create ignore"); CompoID = getImageID(); // Change the LUT of each channel according to the chosen colors a = 1; for (k = 0; k < CHANNEL_COUNT; k++) { if (COLORS_CHOICE[k] == "None") { a--; } else { Stack.setChannel(k + a); setMetadata("Label", LABELS[k + a - 1]); run(COLORS_CHOICE[k]); } } // Save overlay SHORT_NAME = substring(IMAGE_NAMES[i], 0, lengthOf(IMAGE_NAMES[i])-7); OVER_PATH = OUTPUT_DIR + SHORT_NAME + "ov(" + COLOR_CODE + ").tif"; if (FLAT == true) { run("Stack to RGB"); FlatID = getImageID(); selectImage(CompoID); close(); selectImage(FlatID); } save(OVER_PATH); print("Saving to " + OVER_PATH); close(); } // Exit batch mode, display end status, open Stacks folder in the Finder. setBatchMode("exit and display"); print("*** Make_Overlays end ***"); showStatus("Make Overlays finished"); // exec("open", OUTPUT_DIR); }