/* * Macro to process a folder of LIFs into Channel Split and Channel Merged (Projected) images * * #### Change Log #### * v0.1 - 1/23/20 - Initial Version - CK * * v0.2 - 1/30/20 - Changed script to split into up to 4 channels instead of RGB. * Fixed handling of 2 channel images by changing the order in which channel colors are set. - CK * * v0.3 - 2/13/20 - Changed how the script handles saving files. * Added in the ability to pick what colors you want each channel to be. Note the default order is Blue,Green,Red,Cyan. * This script is also limited to handling only 4 channel images. If you somehow managed to image more channels than * that let me know and share with me a test file and we can fix it. * Added better dialog when running the script to make it as clear and easy to use as I can think of * Added a parameter to allow for either a flat single channel RGB output or a multichannel tif output-- CK * * v0.4 - 2/14/20 - Added in an option to use Average Intensity Projection as well as Max Intensity Projection * Added in an option to not project, useful to simply seperate out a lif into z-stacks tifs and set the colors. Still will be easier to work with the files and rename them. * Added all the options for projections to the script * Added a failsafe mode for when the user tries to split the Z-Stack into colors without projecting and trying to save as Flat images, now it will simply split the channels without projecting. * Changed the color suffixes added to the filenames to be 2 letters, for clarity. */ macro "LIFs to TIFs" { #@ String (visibility=MESSAGE, value="

How to use:

  1. Select the folder with the LIF files you want to process.
  2. Check the project box and select the type of projection you want to do.

    - If it is unchecked you are simply seperating the LIF to make it easier to work with.

    - If you are not projecting you can ignore the drop down box.

  3. Check Split Colors if you want to split into individual channels.
  4. Check TIFF Stack box if you want a multi-channel tiff as your maximum intensity projection output.

    - Otherwise the output is a RGB image where adjusting the channel colors will be harder.

  5. Pick the colors you want for the corresponding channels.
    - Do not worry about channels you do not have, if they don't exist in the LIF they will not be in the output.
  6. The output will be in a folder that is named the same as the input folder but with '--Tiff' at the end.
", required=false) msg #@ File (label = "Directory with LIF file(s):", style = "directory") input #@ Boolean (label="Check to project:", value=true, persist=false) should_proj #@ String (label = "Projection Type:", choices={"Max Intensity", "Average Intensity", "Min Intensity", "Sum Slices", "Standard Deviation", "Median"}, style="listBox", value="Max Intensity", persist=false) proj_type #@ Boolean (label = "Check to Split Colors:", persist=false, value=false ) split_colors #@ Boolean (label = "TIFF Stack:", persist=false, value = false) tiff_stack #@ String (label = "Channel 1 color:", choices={"Blue", "Red","Green","Cyan","Magenta","Yellow", "Grays"}, style="listBox", value="Blue", persist=false) channel1_color #@ String (label = "Channel 2 color:", choices={"Blue", "Red","Green","Cyan","Magenta","Yellow", "Grays"}, style="listBox", value="Green", persist=false) channel2_color #@ String (label = "Channel 3 color:", choices={"Blue", "Red","Green","Cyan","Magenta","Yellow", "Grays"}, style="listBox", value="Red", persist=false) channel3_color #@ String (label = "Channel 4 color:", choices={"Blue", "Red","Green","Cyan","Magenta","Yellow", "Grays"}, style="listBox", value="Cyan", persist=false) channel4_color // required for naming the color splits, as imageJ1macro does not support string indexing eq. string[0] channel1_color_first = substring(channel1_color, 0, 2); channel2_color_first = substring(channel2_color, 0, 2); channel3_color_first = substring(channel3_color, 0, 2); channel4_color_first = substring(channel4_color, 0, 2); if (tiff_stack == 0 && split_colors == 1 && should_proj == 0) tiff_stack = 1 ;{} //cant split colors without Projecting unless you are keeping TIF stacks run("Bio-Formats Macro Extensions"); suffix = ".lif"; //global variable thats used inside processFolder(input) setBatchMode(true); processFolder(input); run("Collect Garbage"); //It seems like imageJ isnt gracefully saving things without this. showMessage(" -- Finished! --"); // this allows the user to know when they can look at their files run("Close All"); Ext.close(); setBatchMode(false); // function to scan folders/subfolders/files to find files with correct suffix function processFolder(input) { list = getFileList(input); list = Array.sort(list); inputParent = File.getParent(input); inputName = File.getName(input); // create folders for the tifs output = inputParent+File.separator+inputName+"--Tiff"; if (File.exists(output)==false) { File.makeDirectory(output); // new directory for tiffs } for (k = 0; k < list.length; k++) { if(File.isDirectory(input + File.separator + list[k])) processFolder(input + File.separator + list[k]); if(endsWith(list[k], suffix)) lifToTiffRGBSplit(input, output, list[k]); showProgress(k+1, list.length); } } function splitColors() { if( split_colors == 1 ){ run("Duplicate...", "duplicate"); mergeChannelsFnc(); run("Split Channels"); for (i=1;i<=channels;i++) { selectImage(i); out_path = output + File.separator+name+"_"+seriesname+"_MIP_"+j +" " + color_name[i] +".tif"; saveAs("Tiff", out_path); } } else { mergeChannelsFnc(); } } function mergeChannelsFnc() { if (tiff_stack == 1) { //if (should_proj == 1) { // lets you keep the different channels if projected for the final merged flat image. //run("Make Composite"); saveAs("Tiff", output+File.separator+name+"_"+seriesname+"_MIP_"+j+".tif"); close(); //} else { // this gives us RGB Z stacks output for non-max projected, stacks. essentially just the output of the //run("RGB Color","slices"); //saveAs("Tiff", output+File.separator+name+"_"+seriesname+"_MIP_"+j+".tif"); //close(); //} } else { //this is where i need the logic to fix making tif RGB stacks tiff==1, split_colors==0, Proj == 0 // make a for loop to split each z step, run RGB TRYING run("RGB Color", slices) first run("RGB Color"); saveAs("Tiff", output+File.separator+name+"_"+seriesname+"_MIP_"+j+".tif"); close(); close(); } } function setChannelColors(){ //This function allows the user to set the colors. It is done in reverse order so that if there are less than 4 colors they are still assigned correctly Stack.setChannel(4); run(channel4_color); Stack.setChannel(3); run(channel3_color); Stack.setChannel(2); run(channel2_color); Stack.setChannel(1); run(channel1_color); } //"", , "Standard Deviation", function whichProjToDo() { if (should_proj == 1) { run("Z Project...", "projection=[" + proj_type + "]"); if( proj_type == "Max Intensity"){ proj_prefix = "MAX_"; } else if (proj_type == "Average Intensity") { proj_prefix = "AVG_"; } else if (proj_type == "Min Intensity"){ proj_prefix = "MIN_"; } else if (proj_type == "Sum Slices"){ proj_prefix = "SUM_"; } else if (proj_type == "Standard Deviation"){ proj_prefix = "STD_"; } else if (proj_type == "Median"){ proj_prefix = "MED_"; } return proj_prefix; } else { return 0; } } function lifToTiffRGBSplit(input, output, file) { color_name = newArray(" ", channel1_color_first, channel2_color_first, channel3_color_first , channel4_color_first); // need this for naming the output path= input + File.separator + list[k]; //how many series in this lif file? Ext.setId(path);//-- Initializes the given path (filename). Ext.getSeriesCount(seriesCount); //-- Gets the number of image series in the active dataset. //this is the loop that processes all the images WITHIN the LIF file. for (j=1; j<=seriesCount; j++) { run("Bio-Formats", "open=path autoscale color_mode=Default view=Hyperstack stack_order=XYCZT series_"+j); name=File.nameWithoutExtension; //retrieve name of the series from metadata text=getMetadata("Info"); n1=indexOf(text," Name = ")+8; // the Line in the Metadata reads "Series 0 Name = ". Complete line cannot be taken, because // The number changes of course. But at least in the current version of Metadata this line is the // only occurence of " Name =" n2=indexOf(text,"SizeC = "); // this is the next line in the Metadata seriesname=substring(text, n1, n2-2); seriesname=replace(seriesname,"/","-"); rename(seriesname); getDimensions(w, h, channels, slices, frames); //needed to we know how many channels we are working with, lets the logic work below. //project and save logic if(Stack.isHyperstack) { proj_prefix = whichProjToDo(); if (nSlices>1) Stack.setDisplayMode("composite");{ selectWindow(seriesname); if (should_proj == 1) { close(); //closes non-projected window if the projection was made selectWindow(proj_prefix + seriesname);//selects the projection and works with that. Not needed if not projecting anything } setChannelColors(); splitColors(); } } else if (nSlices>1) { if (nSlices>1) Stack.setDisplayMode("composite");{ setChannelColors(); splitColors(); } } else { Stack.setDisplayMode("composite"); setChannelColors(); splitColors(); } run("Close All"); run("Collect Garbage"); } Ext.close(); } }