/* Michael Cammer mcammer@gmail.com cammem01@nyumc.org Macros for ImageJ Java 1.8 This collection of macros are the ones I like to have on hand most of the time. More at http://microscopynotes.com/imagej/index.html 20180411 In subtract BG in ROI macro, with IJ 1.51 PlotProfile no longer send results to the Results window so rewritten with a measurements loop. */ var clipsize = 150; // edge size of the box for clipping cells for montage var snipwindow = -1; var projectiondepth = 16; // default depth for projection of variable depth var tab = " \t"; /* ============================================================= Should be updated each time macros are edited */ function checkCurrentVersion() { requires('1.52f'); } /* ============================================================= Standard ImageJ allows for installing macros from the macro editor text window by typing ctrl i. Fiji does not. Therefore, to easily update macros in Fiji, change the path of the current macro file being edited in this macro and use ctrl s followed by F4 to reinstall the macros from the Fiji text editor. */ macro "Install Macros [F4]" { run("Install...", "install=[E:/Jessica Treisman/colocalization tests/iterative_results/test_colocalization_20190906.txt]"); } /* It is expected that a two channel image be active when this is run. The two channels will be split. The second channel will be moved for each subsequent colocalization measurement. */ macro "iterate colocalization test" { title = getTitle; run("Split Channels"); ch1 = "C1-"+title; ch2 = "C2-"+title; setPasteMode("Copy"); for (i=0;i<11;i++) { selectImage(ch2); if (i>0) { run("Select All"); run("Copy"); Roi.move(1,0); run("Paste"); run("Select None"); } run("Colocalization Threshold", "channel_1=["+ch1+"] channel_2=["+ch2+"] use=None channel=[Red : Green] show"); // don't include zeros //run("Colocalization Threshold", "channel_1=c1.tif channel_2=c2.tif use=[Channel 1] channel=[Red : Green] show include"); //run("Merge Channels...", "c1=" + ch1 + " c2=" + ch2 +" create keep"); rename(title+i); } // for i } /* works on a stack */ function shift_channel (channel, dx, dy) { Stack.getDimensions(width, height, channels, slices, frames) setPasteMode("Copy"); Stack.setChannel(channel); // does not error check that this is avalid number for (t=1; t<=frames; t++) { Stack.setFrame(t); for (i=1; i<=slices; i++) { Stack.setSlice(i); //Stack.setChannel(channel); // was needed in earlier versions run("Select All"); run("Copy"); Roi.move(dx, dy); run("Paste"); } // for i (slices in Z) } // for t (time) run("Select None"); } // end function shift channel //===================================================================================== // This macro is not ready for general use because it requires programming to work right. // In its current state it moves the field a fixed amount per step and this amount is 1/22. macro "Shift red -4 and 3 down" { Stack.getDimensions(width, height, channels, slices, frames) setPasteMode("Copy"); Stack.setChannel(2); for (t=1; t<=frames; t++) { Stack.setFrame(t); for (i=1; i<=slices; i++) { Stack.setSlice(i); //Stack.setChannel(2); run("Select All"); run("Copy"); Roi.move(-4, 3); run("Paste"); } // for i (slices in Z) } // for t (time) run("Select None"); } // Drift Compensation /*============================================================== */ macro "process TEMs for Milessa [q]" { // Open all images. run("Images to Stack", "name=Stack title=[] use"); run("16-bit"); run("Enhance Contrast...", "saturated=0 normalize process_all"); run("Bandpass Filter...", "filter_large=512 filter_small=0 suppress=None tolerance=5 process"); //run("Image Sequence... ", "format=TIFF digits=2 use save=[E:/2019.7.1 Milessa/C1-C57B16/dark/Stack00.tif]"); } /* ============================================================ SIMPLE FIGURE BASED ON MULTICHANNEL IMAGE DISPLAYED AS IS version 20180930 Makes a montage figure based on a composite image as displayed. The required input is a composite color image. Use adjusts the channels to desied colors and contrast. Running the macro either merges an entire image or the region of interest selected by user. Uses existing contrast without further prompts. But there is a prompt when there are 3, or more channels to find out whether all images in one row or two rows. */ macro "Simple montage figure" { requires("1.52f"); Stack.getDimensions(width, height, channels, slices, frames); if ( (slices>1) || (frames>1) ) exit("Only works for single Z, time, or position images.\nAsk for modification if you need implemented."); if ( (slices > 1) || (frames > 1) ) exit("Requires single Z and single timepoint image"); if (channels < 2) exit("Requires composite color image."); title = getTitleStripExtension(); if (channels < 2) exit("Not a composite image with 2 or more channels."); if (channels == 2) { montageX=3; montageY=1; } if (channels == 3) { Dialog.create("get montage info"); //Dialog.addMessage(); Dialog.create("Radio Buttons"); items = newArray("One row of four panels", "2 X 2 panels"); Dialog.addRadioButtonGroup("Three channels will result in four panels.\nClick which layout preferred.", items, 2, 1, ""); Dialog.show; if ( Dialog.getRadioButton == "One row of four panels") { montageX=4; montageY=1; } else { montageX=2; montageY=2; } } if ((channels==4) || (channels==5)) { Dialog.create("get montage info"); Dialog.create("Radio Buttons"); items = newArray("One row of panels", "3 X 2 panels"); Dialog.addRadioButtonGroup("Click which layout preferred.", items, 2, 1, ""); Dialog.show; if ( Dialog.getRadioButton == "One row of panels") { montageX=channels+1; montageY=1; } else { montageX=3; montageY=2; } } if (channels > 5) exit("Not programmed for more than 5 channels; ask for modification if you need this."); simpleMergeAndMontage (title, montageX, montageY); } /* ========================================= This function does the work for Simple merge as is. It takes a number of arguments. title = text Title of the image, will have montage added to it. montageX = integer How many columns in montage. montageY = integer How many rows in montage. To be implemented in future: grayscale = true/false To be coded someday. This directs the function whether to use LUTs as is or make individual panels in grayscale. */ function simpleMergeAndMontage (title, montageX, montageY) { run("Duplicate...", "duplicate"); rename(title); original = getImageID; run("RGB Color"); // This should make a new window run("Select All"); run("Copy"); setPasteMode("Copy"); close(); selectImage(original); Stack.setDisplayMode("color"); run("RGB Color"); run("Hyperstack to Stack"); setSlice(nSlices); run("Add Slice"); run("Paste"); run("Scale Bar...", "width=10 height=4 font=14 color=[White] background=None location=[Lower Right] bold"); run("Colors...", "foreground=white background=black selection=yellow"); if ((nSlices==5) & (montageY == 2)) { // Make the last panel white if 3 x 2 with only five panels. run("Add Slice"); run("Select All"); run("Fill", "slice"); } run("Select None"); run("Make Montage...", "columns="+montageX+" rows="+montageY+" scale=1 border=2 use"); rename(title+"_montage"); close(title); close(title+" (RGB)"); //Following steps copy the result to the system clipboard for pasting into another application. Only tested on win7. run("Select All"); run("Copy to System"); run("Select None"); } //=========================================================================== macro "Change Values (works on stacks)"{ // as implemented, does not work on multichannel hyperstacks for individual channels run("32-bit"); for (i=1; i<=nSlices(); i++){ setSlice(i); changeValues(0,128,NaN); } } //=========================================================================== // This macro takes all open stacks and projects them. Depending on the filename, in this case // "C=#", the projection method may be different. The projection command automatically names // the new windows with the type of projection followed by the original filename. //=========================================================================== macro "Project all open stacks" { projectAllOpenStacks(); } // "Project all open stacks" function projectAllOpenStacks(){ n = nImages(); for (i=1; i<=n; i++) { selectImage(i); t = getTitleStripExtension(); if ( endsWith(getTitle(), "C=2") ) run("Z Project...", "start=1 stop="+nSlices+" projection=[Min Intensity]"); else run("Z Project...", "start=1 stop="+nSlices+" projection=[Max Intensity]"); rename(t+"_proj"); } // for i } // end projectAllOpenStacks() //=============================================================================== // Extracts the nth slice from a timelapse or Z stack. //=============================================================================== macro "Extract nth slices from stacks" { extract_all_nth_timepoints(2); // change the number in this command to the required slice } function extract_all_nth_timepoints(extract) { // extract is an integer between 1 and nSlices n = nImages(); for (i=1; i<=n; i++) { selectImage(i); t = getTitleStripExtension(); setSlice(extract); title = "M" + extract + "_" + getTitle; run("Duplicate...", "title="+title); rename(t+"_s" + extract); } // for i } macro "=========================="{} //============================================================== // This is for when you already have color images. //macro "box location" { // getCursorLoc(x, y, z, mousestate); // makeRectangle(x-(boxsize/2),y-(boxsize/2), boxsize, boxsize); //} macro "Make snipping box" { makeRectangle(10,10, clipsize, clipsize); } //============================================================== macro "snip out the box [F5]" { roiManager("Add"); run("Duplicate...", "title=[snip]"); } //============================================================================= // calls function clipCellAndPopOnStack(original, clipstack); // macro "clip all ROIs in Roi Manager, center, and put in stack for montage" { original = getImageID; t = getTitle; bits = bitDepth(); if (bits == 24) bitstring="RGB"; else bitstring = ""+bits+"-bit"; clipsize = getNumber("Enter side of square box in pixels: ", clipsize); setPasteMode("Copy"); setBatchMode(true); newImage("snippedstack "+ t, bitstring+" Black", clipsize, clipsize, 1); clipstack = getImageID; for (i=0; iOptions>Colors... //4. Run this macro. // macro 'draw ROI on range of slices in stack'{ checkCurrentVersion(); image_to_process = getImageID(); Dialog.create("draw on slices..."); Dialog.addNumber("first slice to draw on", 1); Dialog.addNumber("last slice to draw on", nSlices()); Dialog.show(); first = Dialog.getNumber(); last = Dialog.getNumber(); if (last < first) { temp=first; first=last; last=temp; } if (first < 1) exit("first slice must be 1 or greater"); if (last > nSlices()) exit("last slice must be the stack size or smaller"); n = roiManager("count"); // get the last ROI in the manager selectImage(image_to_process); roiManager('select', n-1); for (i=first; i<=last; i++){ setSlice(i); run("Draw", "slice"); } // for loop run("Select None"); resetMinAndMax(); } // draw ROI on range of slices in stack /* This macro requires a grayscale stack any bit depth as input. It duplicates this stack twice, thus requiring sufficient RAM. The output is 8 bit per channel RGB. */ macro "RGB merge adjacent slices into a new stack"{ //checkCurrentVersion(); original = getImageID(); t = getTitleStripExtension(); run("Select None"); rename("red"); run("Duplicate...", "title=green duplicate"); setSlice(1); run("Select All"); run("Copy"); run("Add Slice"); run("Paste"); run("Set...", "value=0 slice"); run("Select None"); run("Duplicate...", "title=blue duplicate"); run("Add Slice"); selectWindow("red"); setSlice(nSlices); run("Add Slice"); run("Add Slice"); selectWindow("green"); setSlice(nSlices); run("Add Slice"); run("Merge Channels...", "c1=red c2=green c3=blue"); rename(t+"_runRGB"); } //RGB merge adjacent slices into a new stack //================================================================== /* This macro is for making a movie of a stack that loops, especially useful for animated GIFs of 3D projections that rock back and forth. Downside: doubles the size of the stack. */ macro "Loop stack" { t = getTitle(); run("Duplicate...", "title=xyztemp duplicate"); run("Reverse"); run("Concatenate...", " title="+t+"_3D image1=["+t+"] image2=[xyztemp] image3=[-- None --]"); } macro "make test stack for Projections of variable width" { size = 25; slices = 50; width = 256; newImage("Untitled", "8-bit black", width, width, slices); setColor(255, 255, 255); for (i=1; i= (1/ratio) ) { newWidth = w + (border * w); newHeight = newWidth * ratio; } else { newHeight = h + (border * h); newWidth = newHeight / ratio; } run("Colors...", "foreground=black background=white selection=yellow"); run("Canvas Size...", "width="+newWidth+" height="+newHeight+" position=Center"); } /* =============================================== A future version would have an if statement to check image type and also work on composite images. */ macro "EQ each channel of RGB image" { path = getDirectory("image"); run("RGB Stack"); setSlice(1); run("Enhance Contrast...", "saturated=0 equalize"); setSlice(2); run("Enhance Contrast...", "saturated=0 equalize"); setSlice(3); run("Enhance Contrast...", "saturated=0 equalize"); run("RGB Color"); title = "eq_" + getTitle(); rename(title); // save the new image run("Input/Output...", "jpeg=100 gif=-1 file=.txt use_file copy_column copy_row save_column save_row"); saveAs("Jpeg", path + title); } macro "=====Additional LUTs======"{} /* Additional LUT macros for ImageJ by Michael Cammer Please feel free to use as needed. Other resources: http://imagej.nih.gov/ij/download/luts/ http://rsb.info.nih.gov/ij/macros/ */ //=========================================== macro "Recolor with ratio LUT [F6]"{ requires ('1.38f'); makeFavoriteAIFpseudocolorLUT(); } //=========================================== function makeFavoriteAIFpseudocolorLUT(){ red = newArray(0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123,127,131,135,139,143,147,151,155,159,163,167,171,175,179,183,187,191,195,199,203,207,211,215,219,223,227,231,235,239,243,247,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255); green = newArray(0,1,2,3,4,5,6,7,8,9,10,9,9,8,8,7,7,6,6,5,5,5,4,4,3,3,2,2,1,1,0,0,0,7,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,247,255,247,239,231,223,215,207,199,191,183,175,167,159,151,143,135,128,129,131,132,134,135,137,139,140,142,143,145,147,148,150,151,153,154,156,158,159,161,162,164,166,167,169,170,172,174,175,177,178,180,181,183,185,186,188,189,191,193,194,196,197,199,201,202,204,205,207,208,210,212,213,215,216,218,220,221,223,224,226,228,229,231,232,234,235,237,239,240,242,243,245,247,248,250,251,253,255,251,247,243,239,235,231,227,223,219,215,211,207,203,199,195,191,187,183,179,175,171,167,163,159,155,151,147,143,139,135,131,127,123,119,115,111,107,103,99,95,91,87,83,79,75,71,67,63,59,55,51,47,43,39,35,31,27,23,19,15,11,7,3,0,8,16,24,32,41,49,57,65,74,82,90,98,106,115,123,131,139,148,156,164,172,180,189,197,205,213,222,230,238,246,254); blue = newArray(0,7,15,23,31,39,47,55,63,71,79,87,95,103,111,119,127,135,143,151,159,167,175,183,191,199,207,215,223,231,239,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,251,247,243,239,235,231,227,223,219,215,211,207,203,199,195,191,187,183,179,175,171,167,163,159,155,151,147,143,139,135,131,128,126,124,122,120,118,116,114,112,110,108,106,104,102,100,98,96,94,92,90,88,86,84,82,80,78,76,74,72,70,68,66,64,62,60,58,56,54,52,50,48,46,44,42,40,38,36,34,32,30,28,26,24,22,20,18,16,14,12,10,8,6,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,16,24,32,41,49,57,65,74,82,90,98,106,115,123,131,139,148,156,164,172,180,189,197,205,213,222,230,238,246,254); setLut(red, green, blue); } //=========================================== macro "Orange"{ requires ('1.49'); orange(); } function orange() { red = newArray(256); green = newArray(256); blue = newArray(256); for (i=0; i<256; i++) { red[i] = i; green[i] = i / 2; blue[i] = 0; } // for i setLut(red, green, blue); } //=========================================== macro "Light blue (dapi)"{ requires ('1.49'); lightBlue(); } function lightBlue() { red = newArray(256); green = newArray(256); blue = newArray(256); for (i=0; i<256; i++) { red[i] = 0; green[i] = i / 1.75; blue[i] = i; } // for i setLut(red, green, blue); } //=========================================== macro "HiLo"{ requires ('1.49'); mcHiLoLUT(); } function mcHiLoLUT() { red = newArray(256); green = newArray(256); blue = newArray(256); for (i=0; i<256; i++) { red[i] = i; green[i] = i; blue[i] = i; } // for i blue[255] = 0; blue[0] = 255; green[255] = 63; setLut(red, green, blue); }