/*
* ===================================================================================
* Latest release data: 14.01.2019 (v1.0)
*
* (c) Tarik Exner, Carlo A. Beretta
*
* For any problems, suggestions or bugs, contact Tarik.Exner@med.uni-heidelberg.de
*
* This macro has been published under doi:yyy
* If you use this code for your analysis, please cite as xxx
*
*
* Detects lipid droplets (LDs) in widefield microscopy images and summed Z-stacks.
*
* The script uses a separation procedure containing a bandpass filter for the enhancement of
* LD contrast towards their surrounding structures. LDs are defined as the overlap of
* two geometrical characteristics: A central fluorescence maximum and a circular edge.
*
* ===================================================================================
*/
// ############################################# Functions ###################################################
// 1. Close all the open images before starting the macro
function CloseAllWindows() {
wait(1000);
while(nImages > 0) {
selectImage(nImages);
close();
}
}
// 2. Check plugin installation
function CheckPluginInstallation() {
// Check ImageJ/Fiji version
requires("1.48");
currentVersionScript = "LDquanti v1.0\n";
List.setCommands;
if (List.get("Watershed Segmentation") == "") {
print("Before to start to use this macro you need to install the Classic Watershed Segmentation plugin!");
wait(3000);
print("1. Dowload the Classic Watershed Segmentation plugin at http://bigwww.epfl.ch/sage/soft/watershed/");
exec("open", "http://bigwww.epfl.ch/sage/soft/watershed/");
print("2. Drag and drop the Classic Watershed plugin in the ImageJ/Fiji.app plugin directory");
print("3. After restarting ImageJ/Fiji you should be able to run this macro!");
print("4. Please contact Tarik.Exner@med.uni-heidelberg.de in case of any further issue");
exit();
} else {
print("Running " + currentVersionScript);
print("Classic Watershed plugin is installed!");
}
// Checks if the MorphoLibJ plugin is installed
if (List.get("Morphological Filters") == "" || List.get("Morphological Filters (3D)") == "" || List.get("Directional Filtering") == "") {
Dialog.create("Plugin not found");
Dialog.addMessage("The MorphoLibJ suite is not installed!");
// Add Help button
html = ""
+ "
MorphoLibJ Plugin Installation Steps:
"
+ ""
+ "
1. Go to ImageJ/Fiji
"
+ "
2. Help
"
+ "
3. Update...
"
+ "
4. Manage update sites
"
+ "
5. Enable the IJPB-plugins update website"
+ " (http://sites.imagej.net/IJPB-plugins/)
"
+ "
6. Apply changes and restart ImageJ/Fiji
"
+ "
"
+ "";
Dialog.addHelp(html);
Dialog.show();
exit();
} else {
print("MorphoLibJ is installed!");
print("All necessary plugins are installed!");
wait(2000);
print("\\Clear");
}
}
// 3. Close B&C window
function CloseBCWindow() {
if (isOpen("B&C")) {
selectWindow("B&C");
run("Close");
}
}
// 4. Close the ROI Manager
function CloseROIsManager() {
if (isOpen("ROI Manager")) {
selectWindow("ROI Manager");
run("Close");
}
}
// 5. Open the ROI Manager
function OpenROIsManager() {
if (!isOpen("ROI Manager")) {
run("ROI Manager...");
eval("script","f = WindowManager.getFrame('ROI Manager'); f.setLocation(0,0); f.setSize(10,10);");
}
}
// 6. Close the result window
function CloseResultsWindow() {
if (isOpen("Results")) {
selectWindow("Results");
run("Close");
}
}
// 7. General settings
function Setting() {
// Set the Measurments parameters
run("Set Measurements...", "area redirect=None decimal=3");
run("Input/Output...", "jpeg=100 gif=-1 file=.csv use use_file copy_column copy_row save_column save_row");
// Set binary background to 0
run("Options...", "iterations=1 count=1 white");
}
// 8. Close Log window
function CloseLogWindow(dirOutRoot) {
if (isOpen("Log")) {
selectWindow("Log");
saveAs("txt", dirOutRoot + "Warnings_LOG");
run("Close");
} else {
print("Log window has not been found!");
run("Close");
}
}
// 9. Input dialog box user setting
function InputUserSettingParameters(previewMode) {
width=512; height=512;
experimentTitle = "Insert Title";
ampliCycle = 5;
varBlurring = 1;
blurAfterAmpliNumber = 1;
findMaximum = 4000;
ALT = 5;
lowerSize = 10;
upperSize = 1000000;
lowerCircularity = 0.10;
upperCircularity = 1.00;
volumeDet = false;
blurAfterAmpli = true;
wsBlurring = 2;
savingSetting = true;
loadPrevious = false;
previewMode = false;
Dialog.create("Analysis settings...");
Dialog.addString("Title:", experimentTitle);
Dialog.addMessage("_____________________________________________________________________________");
Dialog.addMessage("Enhancing procedure:");
Dialog.addMessage("");
Dialog.addNumber("Preprocessing Iterations:", ampliCycle, 0, 10, "");
Dialog.addToSameRow();
Dialog.addNumber("Blur During Preprocessing Iterations:", varBlurring, 0, 10, "");
Dialog.addNumber("Blur-Sigma After Preprocessing", blurAfterAmpliNumber, 0, 10, "");
Dialog.addToSameRow();
Dialog.addCheckbox("Blur After Preprocessing", blurAfterAmpli);
Dialog.addMessage("_____________________________________________________________________________");
Dialog.addMessage("LD Number Detection (Maxima):");
Dialog.addMessage("");
Dialog.addNumber("Find Maximum Noise Tolerance:", findMaximum, 0, 10, "");
Dialog.addMessage("_____________________________________________________________________________");
Dialog.addMessage("LD Number Detection (Edges):");
Dialog.addMessage("");
Dialog.addNumber("Auto Local Threshold Radius:", ALT, 0, 10, "");
Dialog.addNumber("Minimum LD Size (in pixel^2):", lowerSize, 0, 10, "");
Dialog.addToSameRow();
Dialog.addNumber("Maximum LD Size (in pixel^2):", upperSize, 0, 10, "");
Dialog.addNumber("Minimum LD Circularity:", lowerCircularity, 0, 10, "");
Dialog.addToSameRow();
Dialog.addNumber("Maximum LD Circularity:", upperCircularity, 0, 10, "");
Dialog.addMessage("_____________________________________________________________________________");
Dialog.addMessage("Volume Estimation:");
Dialog.addMessage("");
Dialog.addCheckbox("Estimate LD Volume", volumeDet);
Dialog.addNumber("Classic Watershed Blurring:", wsBlurring, 0, 10, "");
Dialog.addMessage("_____________________________________________________________________________");
Dialog.addMessage("");
Dialog.addCheckbox("Save settings", savingSetting);
Dialog.addMessage("");
Dialog.addCheckbox("Enter Preview Mode", previewMode);
Dialog.addMessage(" The preview mode will guide you through the crucial steps to evaluate your settings.");
Dialog.addMessage("");
Dialog.addCheckbox("Load previous settings", loadPrevious);
Dialog.show();
experimentTitle = Dialog.getString();
ampliCycle = Dialog.getNumber();
varBlurring = Dialog.getNumber();
blurAfterAmpliNumber = Dialog.getNumber();
findMaximum = Dialog.getNumber();
ALT = Dialog.getNumber();
lowerSize = Dialog.getNumber();
upperSize = Dialog.getNumber();
lowerCircularity = Dialog.getNumber();
upperCircularity = Dialog.getNumber();
blurAfterAmpli = Dialog.getCheckbox();
volumeDet = Dialog.getCheckbox();
wsBlurring = Dialog.getNumber();
savingSetting = Dialog.getCheckbox();
previewMode = Dialog.getCheckbox();
loadPrevious = Dialog.getCheckbox();
if (loadPrevious == true) {
previousSettings = LoadPreviousSettings();
ampliCycle = previousSettings[0]; varBlurring = previousSettings[1]; blurAfterAmpliNumber = previousSettings[3];
findMaximum = previousSettings[4]; ALT = previousSettings[5]; lowerSize = previousSettings[6]; upperSize = previousSettings[7];
lowerCircularity = previousSettings[8]; upperCircularity = previousSettings[9]; blurAfterAmpli = previousSettings[2];
volumeDet = previousSettings[11]; wsBlurring = previousSettings[10];
}
inputDialogSetting = newArray(experimentTitle, ampliCycle, varBlurring, blurAfterAmpliNumber, findMaximum, ALT, lowerSize, upperSize, lowerCircularity, upperCircularity, blurAfterAmpli, volumeDet, wsBlurring, savingSetting, previewMode);
return inputDialogSetting;
}
// 10. Save chosen user setting
function SaveUserSettingParameters(savingSetting, experimentTitle, ampliCycle, blurAfterAmpli, blurAfterAmpliNumber, varBlurring, findMaximum, ALT, lowerSize, upperSize, lowerCircularity, upperCircularity, volumeDet, wsBlurring, dirOutRoot) {
if (savingSetting == true) {
print("Experiment title:\t" + experimentTitle);
print("Preprocessing Iterations:\t" + ampliCycle);
print("Blur During Preprocessing Iterations:\t" + varBlurring);
if (blurAfterAmpli == true) {
print("Blur-Sigma After Preprocessing (sigma):\t" + blurAfterAmpli + "\t(" + blurAfterAmpliNumber + ")");
} else {
print("Blur-Sigma After Preprocessing (sigma):\t" + "0");
}
print("Find Maximum Noise Tolerance:\t" + findMaximum);
print("Auto Local Threshold Radius:\t" + ALT);
print("Minimum LD Size (in pixel^2):\t" + lowerSize);
print("Maximum LD Size (in pixel^2):\t" + upperSize);
print("Minimum LD Circularity:\t" + lowerCircularity);
print("Maximum LD Circularity:\t" + upperCircularity);
if (volumeDet == true) {
print("Classic Watershed Blurring:\t" + wsBlurring);
} else {
print("No volume analysis is performed");
}
saveAs("txt", dirOutRoot + "Experimental_settings");
if (isOpen("Log")) {
selectWindow("Log");
run("Close");
}
}
}
// 11. Track analysis time for documentation
function MacroStartUpTime() {
monthNames = newArray("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
dayNames = newArray("Sun", "Mon","Tue","Wed","Thu","Fri","Sat");
getDateAndTime(year, month, dayOfWeek, dayOfMonth, hour, minute, second, msec);
timeString = "Date: " + dayNames[dayOfWeek] + " ";
if (dayOfMonth<10) {timeString = timeString + "0";}
timeString = timeString + dayOfMonth + "-" + monthNames[month] + "-" + year + "\nTime: ";
if (hour<10) {timeString = timeString + "0";}
timeString = timeString + hour +":";
if (minute<10) {timeString = timeString + "0";}
timeString = timeString + minute + ":";
if (second<10) {timeString = timeString + "0";}
timeString = timeString + second;
return timeString;
}
// 12. Screen location
function ScreenLocation() {
imageWidth = getWidth();
imageHeight = getHeight();
imageReshapeWidth = screenWidth *0.5;
imageReshapeHeight = imageWidth *10;
imageShape = newArray(imageWidth, imageHeight, imageReshapeWidth, imageReshapeHeight);
return imageShape;
}
// 13. Input image calibration and bit depth
function InputImageProperties(title, unit, pixelWidth, pixelHeight) {
// Select input image
selectImage(title);
imageDepth = bitDepth();
getDimensions(width, height, channels, slices, frames);
// Checks if the input file is a multichannels, Z-stacks or a time series
if (channels > 1 || slices > 1 || frames > 1) {
selectWindow("Log");
run("Close");
exit("Multichannels/z-stack/time series images are not supported.");
}
// Checks for image bitdepth
if (imageDepth != 8 && imageDepth != 16) {
selectWindow("Log");
run("Close");
exit ("8-bit or 16-bit images are required.");
}
// Check bit deapth and reset min and max intensity value
if (imageDepth == 16) {
run("Apply LUT");
setMinAndMax(0, 65535);
}
getPixelSize(unit, pixelWidth, pixelHeight);
if (unit != "pixels" || lengthOf(unit) != 1) {
userPixelSize = pixelWidth;
invertedUserPixelSize = 1/userPixelSize;
run("Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=["+userPixelSize+"] pixel_height=["+userPixelSize+"] voxel_depth=["+userPixelSize+"]");
run("Set Scale...", "distance=["+invertedUserPixelSize+"] known=1 pixel=1 unit=micron global");
}
if (unit == "pixels" || lengthOf(unit) == 1) {
Dialog.create("Image Properties");
Dialog.addMessage("Uncalibrated input image");
Dialog.addNumber("Enter the pixel size: ", 0.10638);
Dialog.show();
Dialog.setLocation(255, 255);
userPixelSize = Dialog.getNumber();
invertedUserPixelSize = 1/userPixelSize;
run("Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=["+userPixelSize+"] pixel_height=["+userPixelSize+"] voxel_depth=["+userPixelSize+"]");
run("Set Scale...", "distance=["+invertedUserPixelSize+"] known=1 pixel=1 unit=micron global");
}
imageProperties = newArray(invertedUserPixelSize, imageDepth);
return imageProperties;
}
// 14. Polygon selection
function PolygonSelection(title, imageReshapeWidth, imageReshapeHeight, imageWidth, imageHeight) {
selectImage(title);
setBatchMode("show");
setLocation(0, 0, imageReshapeWidth, imageReshapeHeight);
// Draw a polygon selection around the ROI
setTool("polygon");
waitForUser("Select the Region of Interest. Then press Ok!");
// Update the progress bar
showProgress(0);
// Check if selection exist
type = selectionType();
// If selection does not exist use the whole image
if (type == -1) {
makeRectangle(0, 0, imageWidth, imageHeight);
Roi.setName("ROI_drawn");
roiManager("Add");
}
// Otherwise save the ROI in the ROI manager
if ((type >= 0 && type <= 4) || type == 9) {
Roi.setName("ROI_drawn");
roiManager("Add");
}
// Do not show the images
setBatchMode("hide");
}
// 15. Amplification cycles for deblurring
function AmplificationCircles(imageDepth, ampliCycle, title, saveTitle, varBlurring) {
if (imageDepth == 16) {
for (j=0; j 0) {
done = true;
return b;
}
if (b < -1) {
// End functions
CloseAllWindows(); // 1
CloseLogWindow(dirOutRoot); // 8
CloseBCWindow(); // 3
CloseROIsManager(); // 4
CloseThresholdWindows(); // 21
// Display the image and clear the memory
setBatchMode(false);
call("java.lang.System.gc");
exit("No LDs have been found! Please run the macro with a different setting or without volume analysis.");
}
}
}
// 18. Print summary function (Modified from ImageJ/Fiji Macro Documentation)
function PrintSummary(textSummary) {
titleSummaryWindow = "ParticlesAreaVolume";
titleSummaryOutput = "["+titleSummaryWindow+"]";
outputSummaryText = titleSummaryOutput;
if (!isOpen(titleSummaryWindow)) {
// Create the results window
run("Text Window...", "name="+titleSummaryOutput+" width=90 height=20 menu");
eval("script","f = WindowManager.getFrame('ParticlesAreaVolume'); f.setLocation(0,0); f.setSize(10,10);");
// Print the header and output the first line of text
print(outputSummaryText, "%Id\t" + "%Area(um^2)\t" + "%Volume(um^3)\t" + "\n");
print(outputSummaryText, textSummary +"\n");
} else {
print(outputSummaryText, textSummary +"\n");
}
}
// 19. Check for warning
function Warning(analysisPath, saveTitle, warningException, warningConsole) {
// Prints the console window or exception window if it opens (indicates problems) for further bug-management
if (isOpen("Exception")) {
selectWindow("Exception");
saveAs("txt", analysisPath + "Exception_Log_" + saveTitle);
run("Close");
warningException = true;
}
if (isOpen("Console")) {
selectWindow("Console");
saveAs("txt", analysisPath + "Console_Log_" + saveTitle);
run("Close");
warningConsole = true;
}ยด
outPutWarning = newArray(warningException, warningConsole);
return outPutWarning;
}
// 20. Print warnings
function PrintWarning(warningException, warningConsole, analysisPath, title) {
if (warningException == true || warningConsole == true) {
print("> Warning: Log file can not be found " + analysisPath);
} else {
print("> Processed file: " + title);
}
}
// 21. Close thresholod window
function CloseThresholdWindows() {
if (isOpen("Threshold")) {
selectWindow("Threshold");
run("Close");
}
}
// 22. Load previous settings
function LoadPreviousSettings() {
experiment = getDirectory("Choose the previous experiment directory to load the setting");
if (File.exists(experiment + "experimental_settings.txt")) {
parameters = File.openAsString(experiment + "experimental_settings.txt");
singleParameters = split(parameters,"\n");
ampliCycle = parseInt(replace(singleParameters[1],"Preprocessing Iterations:\t",""));
varBlurring = parseInt(replace(singleParameters[2], "Blur During Preprocessing Iterations:\t", ""));
blurAfterAmpli_raw = replace(singleParameters[3], "Blur-Sigma After Preprocessing \\(sigma\\):\t","");
bracketPosition = indexOf(blurAfterAmpli_raw, "(");
blurAfterAmpli = parseInt(substring(blurAfterAmpli_raw, bracketPosition-2,bracketPosition-1));
blurAfterAmpliNumber = parseInt(substring(blurAfterAmpli_raw, bracketPosition+1, bracketPosition+2));
findMaximum = parseInt(replace(singleParameters[4], "Find Maximum Noise Tolerance:\t", ""));
ALT = parseInt(replace(singleParameters[5], "Auto Local Threshold Radius:\t", ""));
lowerSize = parseInt(replace(singleParameters[6], "Minimum LD Size \\(in pixel\\^2\\):\t", ""));
upperSize = parseInt(replace(singleParameters[7], "Maximum LD Size \\(in pixel\\^2\\):\t", ""));
lowerCircularity = parseFloat(replace(singleParameters[8], "Minimum LD Circularity:\t", ""));
upperCircularity = parseFloat(replace(singleParameters[9], "Maximum LD Circularity:\t",""));
wsBlurring = parseInt(replace(singleParameters[10], "Classic Watershed Blurring:\t",""));
if (isNaN(wsBlurring) == true && File.exists(experiment + "experimental_settings.txt") == true) {
addVolumeAnalysis = getBoolean("Do you want to analyze the LD volume?");
if (addVolumeAnalysis == true) {
volumeDet = true;
Dialog.create("Analysis settings");
Dialog.addNumber("Classic Watershed Blurring:", 2, 0, 7, "");
Dialog.show();
wsBlurring = Dialog.getNumber();
} else {
volumeDet = 0;
wsBlurring = 0;
}
} else {
addVolumeAnalysis = getBoolean("Do you want to analyze the LD volume?");
if (addVolumeAnalysis == true) {
volumeDet = 1;
} else {
volumeDet = 0;
wsBlurring = 0;
}
}
} else {
exit("The analysis setting file is not found.");
}
previousSettings = newArray(ampliCycle, varBlurring, blurAfterAmpli, blurAfterAmpliNumber, findMaximum, ALT, lowerSize, upperSize, lowerCircularity, upperCircularity, wsBlurring, volumeDet);
return previousSettings;
}
// 23. PreviewDialog: Segmentation
function PreviewDialogSegmentation() {
Dialog.create("Analysis settings...");
Dialog.addMessage("_____________________________________________________________________________");
Dialog.addMessage("Preprocessing procedure:");
Dialog.addMessage("");
Dialog.addNumber("Preprocessing Cycles:", ampliCycle, 0, 10, "");
Dialog.addToSameRow();
Dialog.addNumber("Blur During Preprocessing Iterations:", varBlurring, 0, 10, "");
Dialog.addNumber("Blur-Sigma After Preprocessing", blurAfterAmpliNumber, 0, 10, "");
Dialog.addToSameRow();
Dialog.addCheckbox("Blur After Preprocessing", blurAfterAmpli);
Dialog.show();
ampliCycle = Dialog.getNumber();
varBlurring = Dialog.getNumber();
blurAfterAmpliNumber = Dialog.getNumber();
blurAfterAmpli = Dialog.getCheckbox();
previewSegmentationSetting = newArray(ampliCycle, varBlurring, blurAfterAmpli, blurAfterAmpliNumber);
return previewSegmentationSetting;
}
// 24. PreviewDialog: FindMaximum
function PreviewDialogFindMaximum() {
Dialog.create("Analysis settings...");
Dialog.addMessage("_____________________________________________________________________________")
Dialog.addNumber("Find Maximum Noise Tolerance:", findMaximum, 0, 10, "");
Dialog.addMessage("");
Dialog.show();
findMaximum = Dialog.getNumber();
return findMaximum;
}
// 25. PreviewDialog: Edge Detection
function PreviewDialogEdges() {
Dialog.create("Analysis settings...");
Dialog.addMessage("_____________________________________________________________________________");
Dialog.addMessage("LD Number Detection (Edges):");
Dialog.addMessage("");
Dialog.addNumber("Auto Local Threshold Radius:", ALT, 0, 10, "");
Dialog.addNumber("Minimum LD Size (in pixel^2):", lowerSize, 0, 10, "");
Dialog.addToSameRow();
Dialog.addNumber("Maximum LD Size (in pixel^2):", upperSize, 0, 10, "");
Dialog.addNumber("Minimum LD Circularity:", lowerCircularity, 0, 10, "");
Dialog.addToSameRow();
Dialog.addNumber("Maximum LD Circularity:", upperCircularity, 0, 10, "");
Dialog.show();
ALT = Dialog.getNumber();
lowerSize = Dialog.getNumber();
upperSize = Dialog.getNumber();
lowerCircularity = Dialog.getNumber();
upperCircularity = Dialog.getNumber();
previewEdgesSetting = newArray(ALT, lowerSize, upperSize, lowerCircularity, upperCircularity);
return previewEdgesSetting;
}
// 26. PreviewDialog: Classic Watershed
function PreviewDialogClassicWatershed() {
Dialog.create("Analysis settings...");
Dialog.addMessage("_____________________________________________________________________________");
Dialog.addMessage("Volume Estimation:");
Dialog.addNumber("Classic Watershed Blurring:", wsBlurring, 0, 10, "");
Dialog.show();
wsBlurring = Dialog.getNumber;
return wsBlurring;
}
// 27. Print preview Settings to the analysis folder without messing up the log window
function PrintPreviewSettings(savingSetting, experimentTitle, ampliCycle, blurAfterAmpli, blurAfterAmpliNumber, varBlurring, findMaximum, ALT, lowerSize, upperSize, lowerCircularity, upperCircularity, volumeDet, wsBlurring, analysisPath) {
titleWindow = "Preview Mode Settings";
titleOutput = "["+titleWindow+"]";
if (!isOpen(titleWindow)) {
// Create the results window
run("Text Window...", "name="+titleOutput+" width=90 height=20 menu");
eval("script","f = WindowManager.getFrame('Preview Mode Settings'); f.setLocation(0,0); f.setSize(10,10);");
print(titleOutput, "Experiment title:\t" + experimentTitle + "\n");
print(titleOutput, "Preprocessing Iterations:\t" + ampliCycle + "\n");
print(titleOutput, "Blur During Preprocessing Iterations:\t" + varBlurring + "\n");
if (blurAfterAmpli == true) {
print(titleOutput, "Blur-Sigma After Preprocessing (sigma):\t" + blurAfterAmpli + "\t(" + blurAfterAmpliNumber + ")" + "\n");
} else {
print(titleOutput, "Blur-Sigma After Preprocessing (sigma):\t" + "0" + "\n");
}
print(titleOutput, "Find Maximum Noise Tolerance:\t" + findMaximum + "\n");
print(titleOutput, "Auto Local Threshold Radius:\t" + ALT + "\n");
print(titleOutput, "Minimum LD Size (in pixel^2):\t" + lowerSize + "\n");
print(titleOutput, "Maximum LD Size (in pixel^2):\t" + upperSize + "\n");
print(titleOutput, "Minimum LD Circularity:\t" + lowerCircularity + "\n");
print(titleOutput, "Maximum LD Circularity:\t" + upperCircularity + "\n");
if (volumeDet == true) {
print(titleOutput, "Classic Watershed Blurring:\t" + wsBlurring + "\n");
} else {
print(titleOutput, "No volume analysis is performed" + "\n");
}
selectWindow("Preview Mode Settings");
saveAs("Text", analysisPath + "experimental_settings.txt");
run("Close");
}
}
// 28. Merge the volume text windows
function MergeSummaryWindows() {
titleMergedSummary = "Single_LD_Volumes";
titleMergedSummaryOutput = "["+titleMergedSummary+"]";
outputMergedSummaryText = titleMergedSummaryOutput;
run("Text Window...", "name="+titleMergedSummary+" width=90 height=20 menu");
print(outputMergedSummaryText, "%Id\t" + "%Area(um^2)\t" + "%Volume(um^3)\t" );
eval("script","f = WindowManager.getFrame('Single_LD_Volumes'); f.setLocation(0,0); f.setSize(10,10);");
for (aa=0; aa Renaming input image: " + title);
}
return title;
}
// ############################################# MACRO ###################################################
// Use exidecimal code to create the macro logo
macro "LD finding Action Tool - C000D02D03D04D0cD0dD0eD11D12D13D14D1dD21D22D2dD70D80D81D90D91D92Da0Da1Da2Db0Db1Db2Dc0Dc1Dc2Dd0Dd1Dd2Dd3De0De1De2De3Df0Df1Df2Df3Df4C000D1cD31C000D2cD82C000Df5C000D71D93Dc3De4C000Da3C000D15Df6C000D60Db3C000D05D1eC000D23C000D0fC000D01C000C010D24D41C010D61C010D20D32C010D83C010D0bD51Dd4C010D50C010D10C010D1bC010C020D2bC020D2eC020D30C020D25C020Df7C020D72DfdC020De5C020C030D3dC030D40C030DedC040D84C040D16C040D06D1fDc4C040D94C040D26C040D00C040D3cD3eC040C050De6C050DfcC050D42C050Da4C050D33C050DfeC050DecC050C060DbfC060D38D62DdaC060D37D48C060D77C060D2aD87Db4C060D3bD88C060DcfDe7C060Df8C060C070D5fC070D27D52C070De9C070D86C070DeaC070D6fD73DeeC070D34Dd9C070D36D47DebC070D39C070C080D9eDd5C080D4eDaaDe8C080DcaC080D85DdbDddC080D58D8eC080D0aD4fD78C080D3aD9aD9dDbeC080D67D76DaeC080D35DafC080DdeC080D17C090D2fD57C090D99C090D1aDdfC090D3fC090D89DdcC090D68Df9C090Dc9DffC090D4dC090D28DbaC090D7eD95DceC090DfbC0a0D29C0a0D7fD98C0a0D07C0a0DabC0a0D9fC0a0Da9C0a0DadC0a0D5eD74Db9C0a0D43C0a0D8dC0a0D46DefC0a0D6eD75C0a0D49C0b0Dd8C0b0D8fC0b0D96DcbC0b0D18D9cC0b0D97C0b0DbbC0b0D63C0b0D08C0b0D9bC0b0D44DacDc5DcdDd7C0b0Dd6DfaC0b0D79C0c0D09C0c0Da5C0c0D45D8aC0c0DbdC0c0D19Db5C0c0D53D66C0c0C0d0D4cDa8C0d0D56C0d0DbcC0d0DccC0d0D59C0d0D7dC0d0Dc7C0d0D4bDc8C0e0D4aD65C0e0D8cC0e0Db8C0e0D5dD69C0e0D55C0e0D6dC0e0D8bC0e0Da6C0e0D64D7aDb6C0f0Dc6C0f0D54C0f0Da7Db7C0f0D5aC0f0D7cC0f0D7bC0f0D5bD5cD6aD6bD6c [6]" {
// Start up functions
CloseAllWindows(); // 1
CheckPluginInstallation(); // 2
CloseBCWindow(); // 3
CloseROIsManager(); // 4
OpenROIsManager(); // 5
CloseResultsWindow(); // 6
Setting(); // 7
// Choose the input source directory and get the file list
dirIn = getDirectory("Choose the INPUT source directory");
list = getFileList(dirIn);
// General output root path
dirOutRoot = dirIn;
// Tiff/tif file list
files = newArray();
saveTitleArray = newArray();
for (a=0; a Processing input file: 0" + i + "_" + title);
if (i >= 1 && previewMode == true) {
previewMode = getBoolean("Do you want to Run the analysis in Preview mode?");
}
// 12. Set screen location and image size
imageShape = ScreenLocation();
// 29. Replace empty characters in image file name
title = ReplaceEmptyCharc(title);
// Remove input file estention .tiff/tif
dotIndex = indexOf(title, ".");
saveTitle = substring(title, 0, dotIndex);
saveTitleArray = Array.concat(saveTitleArray, saveTitle);
// 13. Function: check input image bit depth and pixel size
// Pixel size unit
getPixelSize(unit, pixelWidth, pixelHeight);
imageProperties = InputImageProperties(title, unit, pixelWidth, pixelHeight);
invertedUserPixelSize = imageProperties[0];
imageDepth = imageProperties[1];
// Duplicate the input image to keep the original input file
selectImage(title);
run("Duplicate...", "title=" + saveTitle + "_original");
title10 = getTitle();
// Create the output directory
analysisPath = dirOutRoot + saveTitle + "_Analysis" + File.separator;
File.makeDirectory(analysisPath);
// 14. Function: polygon selection
imageWidth = imageShape[0];
imageHeight = imageShape[1];
imageReshapeWidth = imageShape[2];
imageReshapeHeight = imageShape[3];
PolygonSelection(title, imageReshapeWidth, imageReshapeHeight, imageWidth, imageHeight);
//////////////////////////////////////////////////////////////////////
///////////////// Amplification/Segmentation Cycles //////////////////
//////////////////////////////////////////////////////////////////////
// Update the progress bar
showProgress(0.2);
while (amplificationResult == 1) {
// Process the input image
selectImage(title);
makeRectangle(0, 0, imageShape[0], imageShape[1]);
// 15. Amplification/Segmentation Cycles
title = AmplificationCircles(imageDepth, ampliCycle, title, saveTitle, varBlurring);
if (previewMode == 1) {
// Display the output image
selectImage(title);
setBatchMode("show");
setLocation(0,0,imageReshapeWidth,imageReshapeHeight);
waitForUser("Filtered image for LD separation\nZoom in to check the LD detection");
amplificationResult = getBoolean("Do you want to repeat the image filtering?");
if (amplificationResult == 1) {
// Close the output of amplifcation
selectImage(title);
close(title);
// Close the Log window
selectWindow("Log");
run("Close");
// Create amplification input image
selectImage(title10);
run("Duplicate...", "title=" + title);
title = getTitle();
// 9. Input dialog box setting
previewSegmentationSetting = PreviewDialogSegmentation();
ampliCycle = previewSegmentationSetting[0]; varBlurring = previewSegmentationSetting[1]; blurAfterAmpli = previewSegmentationSetting[2];
blurAfterAmpliNumber = previewSegmentationSetting[3];
// 11. Update start up macro recording time function
timeString = MacroStartUpTime();
print(timeString, "\n");
print("Processing input file: 0" + i + "_" + title);
previewMode = true;
}
if (amplificationResult == false) {
amplificationResult = false;
}
// Do not display the images
setBatchMode("hide");
} else {
amplificationResult = false;
}
}
while (findMaximumResult == true) {
if (previewMode == true) {
selectImage(title);
roiManager("Select", FindSpecificROI("ROI_drawn"));
run("Find Maxima...", "noise=["+findMaximum+"] output=[Point Selection]");
Roi.setName("total_maxima_found_preliminary");
roiManager("Add");
roiManager("show none");
selectImage(title10);
roiManager("Select", FindSpecificROI("total_maxima_found_preliminary"));
setBatchMode("show");
setLocation(0,0,imageReshapeWidth,imageReshapeHeight);
waitForUser("Overlay of local maxima on raw image.\nZoom in to check if the LDs are properly labeled.");
findMaximumResult = getBoolean("Do you want to adjust the Noise Tolerance?");
if (findMaximumResult == true) {
roiManager("show none");
roiManager("Select", FindSpecificROI("total_maxima_found_preliminary"));
roiManager("Delete");
findMaximum = PreviewDialogFindMaximum();
previewMode = true;
setBatchMode("hide");
} else {
findMaximumResult = false;
roiManager("Select", FindSpecificROI("total_maxima_found_preliminary"));
roiManager("Delete");
setBatchMode("hide");
}
} else {
findMaximumResult = false;
}
}
while (edgeDetectionResult == true) {
if (previewMode == true) {
selectWindow(title);
makePoint(0,0);
setBatchMode("hide");
run("Duplicate...", "title=" + "LD edges");
rename("LD edges");
selectImage("LD edges");
run("Find Edges");
run("8-bit");
run("Auto Local Threshold", "method=Phansalkar radius=["+ALT+"] parameter_1=0 parameter_2=0 white");
run("Invert");
run("Fill Holes");
run("Watershed");
roiManager("select", FindSpecificROI("ROI_drawn"));
run("Analyze Particles...", "size=["+lowerSize+"] - ["+upperSize+"] pixel circularity=["+lowerCircularity+"] - ["+upperCircularity+"] show=Masks");
selectWindow(title10);
setBatchMode("show");
setLocation(0,0,imageReshapeWidth,imageReshapeHeight);
selectImage("Mask of LD edges");
setBatchMode("show");
setLocation(screenWidth/2,0,imageReshapeWidth,imageReshapeHeight);
waitForUser("LD edges. Check if the detection is sufficient.");
edgeDetectionResult = getBoolean("Do you want to repeat the edge detection?");
if (edgeDetectionResult == true) {
selectImage("Mask of LD edges");
close();
if (isOpen("LD edges")) {
selectImage("LD edges");
close();
}
previewEdgesSetting = PreviewDialogEdges();
ALT = previewEdgesSetting[0]; lowerSize = previewEdgesSetting[1]; upperSize = previewEdgesSetting[2];
lowerCircularity = previewEdgesSetting[3]; upperCircularity = previewEdgesSetting[4];
previewMode = true;
} else {
setBatchMode("hide");
if (isOpen("Mask of LD edges")) {
selectImage("Mask of LD edges");
close();
}
if (isOpen("LD edges")) {
selectImage("LD edges");
close();
}
}
} else {
edgeDetectionResult = false;
}
}
// Hide the duplicated original image
selectImage(title10);
setBatchMode("hide");
// Duplicate the input image for edges detection
selectImage(title);
run("Duplicate...", "title=" + saveTitle + "_LD_edges");
title6 = getTitle();
//////////////////////////////////////////////////////////////////////
///////////////////// Volume Determination ///////////////////////////
//////////////////////////////////////////////////////////////////////
if (volumeDet == true) {
while (classicWatershedResult == true) {
// Update the progress bar
showProgress(0.3);
selectImage(title6);
run("Duplicate...", "title=" + saveTitle + "_volumes");
title16 = getTitle();
// Select the ROI using the ROI name
roiManager("Select", FindSpecificROI("ROI_drawn"));
if(blurAfterAmpli == true) {
run("Gaussian Blur...", "sigma=["+blurAfterAmpliNumber+"]");
}
// Find maxima
run("Find Maxima...", "noise=["+findMaximum+"] output=[Point Selection]");
Roi.setName("total_maxima_found");
roiManager("Add");
selectImage(title16);
run("8-bit");
run("Duplicate...", "title=" + saveTitle + "_temp_edge");
title18 = getTitle();
// *** Morphological reconstruction using the maxima defined above => lipid droplets get an area
run("Find Edges");
run("Auto Local Threshold", "method=Phansalkar radius=["+ALT+"] parameter_1=0 parameter_2=0 white");
run("Invert");
run("Fill Holes");
run("Analyze Particles...", "size=["+lowerSize+"] - ["+upperSize+"] pixel circularity=0.00-1.00 show=Masks clear");
selectImage("Mask of " + title18);
title18Mask = getTitle();
roiManager("Select", FindSpecificROI("total_maxima_found"));
run("Interactive Morphological Reconstruction", "type=[By Dilation] connectivity=8");
rename(saveTitle + "_reconstructed");
run("Invert");
title20 = getTitle();
// Close image no longer used
selectImage(title18Mask);
close(title18Mask);
selectImage(title18);
close(title18);
// ***
selectImage(title16);
makeRectangle(0, 0, 0, 0);
run("Gaussian Blur...", "sigma=["+wsBlurring+"]");
imageCalculator("Subtract create 32-bit", title16, title20);
rename(saveTitle + "_watershedding");
title19 = getTitle();
setMinAndMax(0, 255);
run("8-bit");
setMinAndMax(0,255);
run("Invert");
// Close images not longer used
selectImage(title16);
close(title16);
selectImage(title20);
close(title20);
selectImage(title19);
nBins = 256;
getHistogram(values, counts, nBins);
row = 0;
for (x=0; x 1) {
run("Find Maxima...", "noise=1 output=[Point Selection]");
Roi.setName("overlayed_counted_lipid_droplets");
roiManager("Add");
}
if (numberFound <= 1) {
print("No LDs were detected in " + saveTitle + ".\nPlease adjust the settings if this is not intended.\n");
newImage("temp", "8-bit white", imageShape[0], imageShape[1], 1);
temptitle = getTitle();
roiManager("Select", FindSpecificROI("total_maxima_found"));
setMinAndMax(255, 255);
run("Apply LUT");
run("Find Maxima...", "noise=1 output=[Point Selection]");
Roi.setName("overlayed_counted_lipid_droplets");
roiManager("Add");
selectImage(temptitle);
run("Close");
}
//
newImage(saveTitle + "_FM_only", "8-bit white", imageShape[0], imageShape[1], 1);
title11 = getTitle();
roiManager("Select", FindSpecificROI("total_maxima_found"));
setMinAndMax(255, 255);
run("Apply LUT");
run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Nothing summarize");
// Measure maxima that overlayed with edge-particles
if (numberFound > 1) {
newImage(saveTitle + "_FM_edge_overlay", "8-bit white", imageShape[0], imageShape[1], 1);
title12 = getTitle();
roiManager("Select", FindSpecificROI("overlayed_counted_lipid_droplets"));
setMinAndMax(255, 255);
run("Apply LUT");
run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Nothing summarize");
} else {
newImage(saveTitle + "_FM_edge_overlay", "8-bit white", imageShape[0], imageShape[1], 1);
title12 = getTitle();
run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Nothing summarize");
}
// ROIs are saved, partly individually, in the corresponding analysis folder.
roiManager("Select", FindSpecificROI("overlayed_counted_lipid_droplets"));
saveAs("Selection", analysisPath + "overlayed_counted_lipid_droplets");
roiManager("Select", FindSpecificROI("total_maxima_found"));
saveAs("Selection", analysisPath + "total_maxima_found");
roiManager("deselect");
roiManager("Save", analysisPath + "edge_particles_and_maxima" + ".zip");
// Close the images not longer used
selectImage(title6);
close(title6);
selectImage(title7);
close(title7);
selectImage(title8);
close(title8);
selectImage(title9);
close(title9);
selectImage(title11);
close(title11);
selectImage(title12);
close(title12);
// Update the progress bar
showProgress(0.8);
// Make an image with both ROIs as a colored overlap and save the image
selectImage(title10);
run("Duplicate...", "title=" + saveTitle + "_single_ROI");
title14 = getTitle();
roiManager("Select", FindSpecificROI("total_maxima_found"));
run("Properties... ", "stroke=red point=Dot size=Tiny");
run("Add Selection...");
roiManager("Deselect");
roiManager("Select", FindSpecificROI("overlayed_counted_lipid_droplets"));
run("Properties... ", "stroke=green point=Dot size=Tiny");
run("Add Selection...");
saveAs("jpeg", analysisPath + saveTitle + "_both_maxima");
title14 = getTitle();
if (previewMode == true) {
setBatchMode("show");
setLocation(0,0,imageReshapeWidth,imageReshapeHeight);
waitForUser("Please check if the LD detection is accurate.\nGreen dots indicate positive LDs, red dots indicate false positive LDs");
LDDetectionResult = getBoolean("Is the LD detection correct?");
if (LDDetectionResult==false) {
startOver = getBoolean("Do you want to process the same image again?");
if (startOver == true) {
i=i-1;
}
}
if (savingSetting == true) {
PrintPreviewSettings(savingSetting, experimentTitle, ampliCycle, blurAfterAmpli, blurAfterAmpliNumber, varBlurring, findMaximum, ALT, lowerSize, upperSize, lowerCircularity, upperCircularity, volumeDet, wsBlurring, analysisPath);
}
print("\nWarning: Overwriting previous setting. The new setting is applied to all the images starting from: " + title, "\nThe Settings is saved in the respective analysis folder");
}
//
selectImage(title10);
run("Duplicate...", "title=" + saveTitle + "_edge_ROI");
title15 = getTitle();
roiManager("Select", FindSpecificROI("overlayed_counted_lipid_droplets"));
roiManager("delete");
roiManager("Select", FindSpecificROI("total_maxima_found"));
roiManager("delete");
roiManager("Show All without labels");
run("Flatten");
title15Flat = getTitle();
saveAs("jpeg", analysisPath + saveTitle + "_edges");
title15Flat = getTitle();
// Update the progress bar
showProgress(0.9);
// Save the input image
selectImage(title10);
saveAs("jpeg", analysisPath + saveTitle + "_original");
title10 = getTitle();
// Reset the scale
if (i == files.length-1) {
run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel");
}
close(title10);
// Close all the open images one-by-one
selectImage(title14);
close(title14);
selectImage(title15);
close(title15);
selectImage(title15Flat);
close(title15Flat);
selectImage(title);
close(title);
// Close results window
CloseResultsWindow();
// Clear the roiManger
roiManager("reset");
// 19. Check for warnings
outPutWarning = Warning(analysisPath, saveTitle, warningException, warningConsole);
warningException = outPutWarning[0];
warningConsole = outPutWarning[1];
// 20. Print warnings
PrintWarning(warningException, warningConsole, analysisPath, title);
// Update the progress bar
showProgress(1);
}
}
// Save the summary table
if (isOpen("Summary")) {
selectWindow("Summary");
eval("script","f = WindowManager.getFrame('Summary'); f.setLocation(0,0); f.setSize(500,500);");
selectWindow("Summary");
tableTitle = "Summary";
firstFolderName = File.getName(dirIn);
secondFolder = File.getParent(dirIn); secondFolderName = File.getName(secondFolder);
thirdFolder = File.getParent(secondFolder); thirdFolderName = File.getName(thirdFolder);
forthFolder = File.getParent(thirdFolder); forthFolderName = File.getName(forthFolder);
saveAs("results", dirIn + tableTitle + "_" + experimentTitle + "_" + forthFolderName + "_" + thirdFolderName + "_" + secondFolderName + "_" + firstFolderName + ".xls");
}
if (isOpen("Log")) {
// Enlarges the Log window for better visibility
selectWindow("Log");
eval("script","f = WindowManager.getFrame('Log'); f.setLocation(0,500); f.setSize(500,500);");
}
// Output processing speed
stop = getTime();
seconds = (stop - start) /1000;
speed = files.length /seconds;
if (files.length == 1) {
print("\nProcessed " + files.length + " file in " + seconds + " seconds!\n");
}
if (files.length != 1) {
print("\nProcessed " + files.length + " files in " + seconds + " seconds!\n");
}
if (volumeDet == true) {
print("\nCalculating final volume dataset...\n");
MergeSummaryWindows();
}
// End functions
print("\n%%% Congratulation your files have been successfully processed %%%\n");
CloseBCWindow(); // 3
CloseROIsManager(); // 4
CloseThresholdWindows(); // 21
wait(3000);
CloseLogWindow(dirOutRoot); // 8
// Display the images and clear the memory
setBatchMode(false);
call("java.lang.System.gc");
// Display status
showStatus("Finished!");
wait(1000);
}