// FAST (Fluorescence image AnalysiS Tool) - Cyril TURIÈS - Comments or improvements are welcome (mailto: cyril.turies@ineris.fr) // Image processing pipeline: // - List all files containing user-defined extension (.czi .zvi .nd2 or .tif) within selected directory and sub-directories // - Apply the user-defined threshold (default 290) then analyse particles above the threshold // - Group all pixels above the threshold in one Region Of Interest and save this ROI in a zip file within work directory // - Open images one by one to check the auto-selected area // - User can confirm the ROI, modify it directly or remove image from further analysis // - result table is automatically copied to clipboard at the end of the macro // List of updates: // - 10/2014 added help message accessible from dialogBox to explain tickboxes // - 10/2014 added silent mode for new measurement of existing data without prompt // - 10/2014 CSV saving option in work directory // - 10/2014 added upper/lower case image selection // - 01/2015 fixed bug reseting result table // - 01/2015 add new Zeiss ZEN .czi file format and Dialog.setLocation() // - 06/2016 Restart Mode to restart analysis after interruption of auto processing // - 02/2018 added Nikon .nd2 file type // - 07/2018 Former name "Cyp19a1b-GFP Analysis" changed to FAST (Fluorescence image AnalysiS Tool) // - 08/2018 Saves user threshold and file type in ImageJ Prefs // - 08/2018 Added "Other" for supported Bio-Formats file types not listed in startup options v = "v2.4"; date = "08/2018"; requires("1.49o"); // 1.49o23 run("Bio-Formats Macro Extensions"); // DialogBox Help message help = "" +"

FAST (Fluorescence image AnalysiS Tool) help

" +"Threshold : set threshold value for pixel intensity, segmenting the image
into features of interest (above threshold) and background.

" +"File type : select image type or extension between CZI (ZEN Zeiss format)
" +"ZVI (Zeiss Vision Image), ND2 Nikon file and TIFF (Tagged Image File Format),
'Other' allow to enter a specific file extension.

" +"Create ROIs : Step 1, Analyse pixels above the user-defined threshold value
" +"and automatically saves Regions Of Interest zip file in the image directory.

" +"Measure ROIs : Step 2 of image analysis to check individually
and measure previously created ROIs.
" +"(With Step 1 unchecked and Step 2 checked, user can reanalyse previous data).

" +"Overwrite existing ROIs : if selected, the macro will overwrite ROIs zip files
without prompting the user every time.

" +"Silent Mode : if selected, the macro will measure the ROI of all images
without prompting the user every time. (Useful for reanalysis of previous data).

" +"Restart Mode : when auto processing is cancelled accidentally,
this mode checks the last ROI created and restarts analysis from this point.

" +"*ROI = Region Of Interest

" +"For a detailed description see: http://imagej.net/FAST
" +"-> Any comment/improvement is welcome cyril.turies@ineris.fr" +v+" - "+date +""; // Recover User variables from ImageJ Prefs UserThr = call("ij.Prefs.get", "FAST.user.thr", "unset"); if (UserThr == "unset") UserThr = 290; UserFtype = call("ij.Prefs.get", "FAST.user.ftype", "unset"); if (UserFtype == "unset") UserFtype = ".czi"; UserOTHtype = call("ij.Prefs.get", "FAST.user.othtype", "unset"); if (UserOTHtype == "unset") UserOTHtype = ".nd2"; // DialogBox to set options Dialog.create("FAST "+v+" options"); Dialog.addChoice("File type", newArray(".czi",".zvi",".tif",".nd2","Other"), UserFtype); Dialog.addNumber("Threshold value:", UserThr); Dialog.setInsets(0, 0, 0); Dialog.addMessage("Images auto processing:"); Dialog.setInsets(0, 20, 0); Dialog.addCheckbox("Create Regions Of Interest (Step 1)", true); Dialog.addCheckbox("Measure ROIs (Step 2)", true); Dialog.setInsets(0, 0, 0); Dialog.addMessage("Specific parameters: (see Help)"); Dialog.setInsets(0, 40, 0); Dialog.addCheckbox("Overwrite existing ROIs", false); Dialog.setInsets(0, 40, 0); Dialog.addCheckbox("Silent Mode", false); Dialog.setInsets(0, 40, 0); Dialog.addCheckbox("Restart Mode", false); Dialog.addHelp(help); Dialog.show(); ext = Dialog.getChoice(); thr = Dialog.getNumber(); def = Dialog.getCheckbox(); mes = Dialog.getCheckbox(); overwrt = Dialog.getCheckbox(); silent = Dialog.getCheckbox(); resume = Dialog.getCheckbox(); // Save User preferences in ImageJ.Pref call("ij.Prefs.set", "FAST.user.thr", thr); call("ij.Prefs.set", "FAST.user.ftype", ext); // Get extension not listed in File types if (ext == "Other") { Dialog.create("Please enter file extension"); Dialog.setInsets(0, 20, 0); Dialog.addString("Extension:", UserOTHtype); Dialog.addMessage("DO NOT remove the . before extension"); Dialog.show(); ext = Dialog.getString(); call("ij.Prefs.set", "FAST.user.othtype", ext); } // Select work directory dir = getDirectory("Choose a Directory "); svdir = dir; k = 1; // Reset ROI Manager c = roiManager("count"); if (c != 0) { showMessageWithCancel("Warning!","Content of ROI manager will be erased\nContinue?"); roiManager("reset"); } // test for upper-case extension upext = toUpperCase(ext); // Auto threshold, select ROI and autosave setBatchMode(true); if (def == true) listFiles(dir); setBatchMode(false); // Goto image 1 to check each ROI k = 1; run("Set Measurements...", "area mean standard min integrated limit display redirect=None decimal=0"); // Reset result table if (nResults != 0) { // showMessageWithCancel("Warning!","Content of Result Table will be erased"); run("Clear Results"); } // Individual check of ROI if (mes == true) { // Activate batchmode to stop blinking of images if (silent == 1){ setBatchMode(true); checkFiles(dir); setBatchMode(false); } else { checkFiles(dir); } updateResults(); if (nResults == 0) { print("No image corresponding to extention, found in selected directory"); print("OR"); print("File extension is not supported by Bio-Formats"); } else { svchoice = getBoolean("Do you want to save the\nResult table to work directory?"); selectWindow("Results"); if (svchoice == 1) { if (File.exists(svdir+"Results.csv")) { choice = getBoolean("A file named Results.csv\nalready exists. Overwrite?"); if (choice == 1) saveAs("Results", svdir+"Results.csv"); if (choice == 0) { newdir = getDirectory("Save to"); saveAs("Results", newdir+"Results.csv"); } } else saveAs("Results", svdir+"Results.csv"); } } } /////////////////////////////////// // Fonction "listfile" to select pixel area above user-defined threshold and auto save of ROI into [imagename].zip file function listFiles(dir) { list = getFileList(dir); for (i=0; i1) { roiManager("deselect"); roiManager("XOR"); roiManager("add"); for (j=1; j0) { // check of existing ROI.zip if (File.exists(dir+prefix+".zip")) { if (overwrt == 1) { roiManager("Save", dir+prefix+".zip"); } else { choice = getBoolean("A file named "+prefix+".zip already exists.\nOverwrite?"); if (choice == 1) roiManager("Save", dir+prefix+".zip"); } } else { roiManager("Save", dir+prefix+".zip"); } roiManager("reset"); } close(); } } } } } // Fonction "checkfiles" to individually check pixel area above user-defined threshold function checkFiles(dir) { list = getFileList(dir); for (i=0; i "+prefix); items = newArray("Yes", "No"); Dialog.addRadioButtonGroup("Exclude image from analysis:", items, 1, 2, "No"); Dialog.addRadioButtonGroup("Redefine area manually:", items, 1, 2, "No"); Dialog.setLocation(x+width,y); Dialog.show; skip = Dialog.getRadioButton; area = Dialog.getRadioButton; if (skip == "Yes") { close(); roiManager("reset"); } else { if (area == "Yes") { roiManager("reset"); resetThreshold; getMinAndMax(min, max); setThreshold(thr, max, "over/under"); run("Analyze Particles...", "size=2-Infinity exclude include add"); setTool("freehand"); waitForUser("ROI edition","Edit area before you click on OK\n\nPress and hold key:\n ALT = Substract selected area \n SHIFT = Add selected area"); if (selectionType() == -1) waitForUser("WARNING","Without selection this image will be excluded from analysis\n \n=> Select area then click on -OK-"); if (selectionType() != -1) { roiManager("add"); roiManager("Save", dir+prefix+".zip"); roiManager("deselect"); roiManager("Measure"); roiManager("reset"); setResult("Label", nResults-1, list[i]); } } if (area == "No") { resetThreshold; getMinAndMax(min, max); setThreshold(thr, max, "over/under"); roiManager("deselect"); roiManager("Measure"); roiManager("reset"); setResult("Label", nResults-1, list[i]); } updateResults(); close(); } } } else { // Silent mode if no ROI is found if (silent == 1){ print("No ROI.zip for: "+dir+prefix); close(); // Normal mode if no pixel found in ROI } else { choice = getBoolean("No pixel area >> threshold found on the image.\n \nExclude image from analysis?\n| Yes | = Exclude\n| No | = Redefine area"); if (choice == 0) { roiManager("reset"); resetThreshold; run("Select None"); getMinAndMax(min, max); setThreshold(thr, max, "over/under"); setTool("freehand"); waitForUser("Area selection","Select new area\nbefore you click on OK"); if (selectionType() == -1) waitForUser("WARNING","Without selection this image will be excluded from analysis\n \n=> Select area then click on -OK-"); if (selectionType() != -1) { roiManager("add"); roiManager("Save", dir+prefix+".zip"); roiManager("deselect"); roiManager("Measure"); roiManager("reset"); setResult("Label", nResults-1, list[i]); updateResults(); } close(); } if (choice == 1) { close(); } } } } } } }