/* - WEKA-FISH V2 - Fiji
* - Virginia Polytechnic Institute and State University
* - Biocomplexity Institute - Hauf Lab
* - Erod Keaton Baybay
*
* Disclaimer:
* Way more comments than necessary are in use for educational, self-teaching, self-referencing purposes.
* Because Erod is extremely forgetful, and tends to forget what certain things do.
*
* Note that the cleanAll() function will close images without saving.
* Please save your work prior to running this Macro.
*/
requires("1.52e"); // Required FIJI Version
var WFv = "3.0b"; // WEKA-FISH Pipeline Version
macro "WEKA-FISH"
{
run("Collect Garbage");
t0 = getTime();
showMessageWithCancel("WEKA-FISH "+WFv, ""
+"
WEKA-FISH
"
+"Hauf Lab - Biocomplexity Institute 2018"
+""
+"- Pipeline Version: "+WFv
+"
- FIJI Version Required: 1.52e"
+"
- Designed for FISHquant v3a (MATLAB 2016b)"
+"
"
+"Please read accompanying documentation"
+"[Erod Keaton Baybay - erodb@vt.edu]");
// Default Parameters
cleanAll();
flat = false;
limitSize = 5;
bins = 20
thresh = 0.99;
// ------- Initialization I - File Designation -----------------------------------------------------------------------
showStatus("Initializing WEKA-FISH...");
run("Set Measurements...", "area centroid fit display redirect=None decimal=3");
waitForUser("Please select an Output Directory");
outputDirectory = getDirectory("Choose an Output Directory");
showStatus("Initializing WEKA-FISH... [Autofluorescence Image]");
waitForUser("Please select an Autofluorescence Image (CFP or GFP)");
AFPimage = File.openDialog("Choose Autoflouresence Image");
showStatus("Initializing WEKA-FISH... [DAPI Image]");
waitForUser("Please select a Nuclear Tracking Image (DAPI)");
DAPIimage = File.openDialog("Choose Nuclear Tracking Image");
showStatus("Initializing WEKA-FISH... [Raw Image]");
waitForUser("Please select a Raw Image (FISHRed)");
RAWimage = File.openDialog("Choose Raw Image");
getDateAndTime(year, month, dayOfWeek, dayOfMonth, hour, minute, second, msec);
saveID = ""+year+""+month+""+dayOfMonth+"_"+hour+""+minute+"_"+replace(File.getName(RAWimage), ".","_");
logID = ""+year+""+month+""+dayOfMonth+"_"+hour+""+minute;
print("WEKA-FISH "+WFv);
print("Hauf Lab - Biocomplexity Institute 2018");
print("Main Save ID: "+saveID);
directoryMain = outputDirectory+"/"+saveID+"/"
if (!File.exists(directoryMain))
File.makeDirectory(directoryMain);
directoryData = directoryMain+"/Data/";
if (!File.exists(directoryData))
File.makeDirectory(directoryData);
directoryHistogram = directoryData+"/Histograms/";
if (!File.exists(directoryHistogram))
File.makeDirectory(directoryHistogram);
directoryROIs = directoryMain+"/ROIs/";
if (!File.exists(directoryROIs))
File.makeDirectory(directoryROIs);
directoryImages = directoryMain+"/Images/";
if (!File.exists(directoryImages))
File.makeDirectory(directoryImages);
directoryOverlays = directoryImages+"/Overlays/";
if (!File.exists(directoryOverlays))
File.makeDirectory(directoryOverlays);
Dialog.create("Run Parameters");
Dialog.addCheckbox("Flatfielded Images", flat);
Dialog.addNumber("Pixel Margin: ", limitSize);
Dialog.addNumber("Histogram Bins: ", bins);
Dialog.addSlider("Training Threshold:", 0.8, 1, thresh);
Dialog.show
flat = Dialog.getCheckbox();
limitSize = Dialog.getNumber;
bins = Dialog.getNumber;
thresh = Dialog.getNumber;
print("\n[Run Parameters]");
print("Subtract Background: ", flat);
print("Pixel Margin: ", limitSize);
print("Histogram Bins: ", bins);
print("Training Threshold:", thresh);
// ------- Phase One - Autoflouresence Preprocessing --------------------------------------------------------------
open(AFPimage);
waitForUser("Please select the most in focus slice.\nOnce selected, click OK.");
showStatus("Processing Autofluorescence Image...");
run("Duplicate...", " ");
// Focused AFP Export
AFPfocus = directoryImages+"/IMG0_"+replace(File.getName(RAWimage), ".","_")+"_Focal_Frame_AFP.tif";
if (!File.exists(AFPfocus))
{
saveAs(".tiff", AFPfocus);
}
run("Enhance Contrast...", "saturated=1 normalize");
run("Gaussian Blur...", "sigma=2");
if(!flat)
run("Subtract Background...", "rolling=50");
run("Enhance Contrast...", "saturated=1 normalize");
run("Unsharp Mask...", "radius=40 mask=0.30");
// Pre-Process Image Export
preProc = directoryImages+"/IMG1_"+replace(File.getName(RAWimage), ".","_")+"_Pre_Processed.tif";
if (!File.exists(preProc))
{
saveAs(".tiff", preProc);
}
print("\n[WEKA Log]");
run("Trainable Weka Segmentation");
showStatus("Running Trainable Weka Segmentation...");
// ------- Phase Two - Autoflouresence Processing --------------------------------------------------------------
waitForUser("Please generate the Probability Map.\nLoad classifier > Get probability\nOnce available, click OK.");
selectWindow("Probability maps");
// Probability Map Image Export
probMap = directoryImages+"/IMG2_"+replace(File.getName(RAWimage), ".","_")+"_Probability_Map.tif";
if (!File.exists(probMap))
{
saveAs(".tiff", probMap);
}
setSlice(2);
run("Duplicate...", " ");
setThreshold(thresh,1);
run("Convert to Mask");
run("Fill Holes");
run("Erode");
run("Gaussian Blur...", "sigma=5");
run("Make Binary", "method=Otsu background=Default calculate black");
run("Analyze Particles...", "size=20-Infinity circularity=0.00-0.80 exclude clear add"); // Clears ROI Manager
// ------- Phase Three - Autoflouresence Postprocessing --------------------------------------------------------------
n = roiManager("count");
roiManager("Show All without labels");
if (n > 0)
{
for (i = 0; i < n; i++)
{
showStatus("Sculpting Cell ROIs...");
roiManager("Select", i);
run("Enlarge...", "enlarge=25");
run("Enlarge...", "enlarge=-20");
run("Convex Hull");
roiManager("Update");
roiManager("Set Color", "green");
roiManager("Set Line Width", 3);
roiManager("Rename", "Cell_"+(i+1));
showStatus("Sculpting Cell ROIs...");
showProgress(i, n-1);
}
}
roiManager("Select", Array.getSequence(roiManager("Count")));
roiManager("Measure");
print("\n[Cell Measurement Report]");
print("Measurements: "+nResults+" Datapoints corresponding to "+roiManager("Count")+" Cells ROIs");
showStatus("Generating Histograms...");
// Cell Size Histogram Export
run("Distribution...", "parameter=Area or="+bins+" and=0-0");
histogram1a = directoryHistogram+"/"+replace(File.getName(RAWimage), ".","_")+"_Cell_Size_Histogram.png";
if (!File.exists(histogram1a))
{
selectImage("Area Distribution");
saveAs(".png", histogram1a);
}
// Cell Length Histogram Export
run("Distribution...", "parameter=Major or="+bins+" and=0-0");
histogram1b = directoryHistogram+"/"+replace(File.getName(RAWimage), ".","_")+"_Cell_Length_Histogram.png";
if (!File.exists(histogram1b))
{
selectImage("Major Distribution");
saveAs(".png", histogram1b);
}
// Cell Width Histogram Export
run("Distribution...", "parameter=Minor or="+bins+" and=0-0");
histogram1c = directoryHistogram+"/"+replace(File.getName(RAWimage), ".","_")+"_Cell_Width_Histogram.png";
if (!File.exists(histogram1c))
{
selectImage("Minor Distribution");
saveAs(".png", histogram1c);
}
// Cell Size File Export
resultFile1 = directoryData+"/"+replace(File.getName(RAWimage), ".","_")+"_Cell_Size.csv";
if (!File.exists(resultFile1))
{
selectWindow("Results");
saveAs("Results", resultFile1);
}
// ------- Phase Four - Nuclear Tracking --------------------------------------------------------------
close('*');
run("Clear Results");
open(DAPIimage);
waitForUser("Please select the most in focus slice.\nOnce selected, click OK.");
s = getSliceNumber();
sMinor = s-5;
sMajor = s+5;
run("Duplicate...", "duplicate range="+sMinor+"-"+sMajor);
run("Z Project...", "projection=[Max Intensity]");
// Focused DAPI Export
DAPIfocus = directoryImages+"/IMG3_"+replace(File.getName(RAWimage), ".","_")+"_Focal_Frame_DAPI.tif";
if (!File.exists(DAPIfocus))
{
saveAs(".tiff", DAPIfocus);
}
run("Enhance Contrast...", "saturated=0.3 normalize");
run("Multiply...", "value=1.7");
if(!flat)
run("Subtract Background...", "rolling=500");
run("Maximum...", "radius=2");
run("Gamma...", "value=4");
run("Make Binary", "method=Otsu background=Default calculate black");
run("Fill Holes");
// Nuclear Binary Image Export
nucBinary = directoryImages+"/IMG4_"+replace(File.getName(RAWimage), ".","_")+"_Nuclear_Binary.tif";
if (!File.exists(nucBinary))
{
saveAs(".tiff", nucBinary);
}
run("Analyze Particles...", "size=100-Infinity circularity=0.50-1.00 exclude add"); // Does not Clear ROI Manager
m = roiManager("count") - n;
roiManager("Show All without labels");
if (m > 0)
{
for (i = 0; i < m; i++)
{
showStatus("Sculpting Nuclear ROIs... ");
roiManager("Select", n+i);
run("Enlarge...", "enlarge=1");
run("Fit Ellipse");
roiManager("Update");
roiManager("Set Color", "red");
roiManager("Set Line Width", 2);
roiManager("Rename", "Nucleus_"+(i+1));
showStatus("Sculpting Nuclear ROIs...");
showProgress(i, m-1);
}
}
roiManager("Select", Array.reverse(Array.trim(Array.reverse(Array.getSequence(roiManager("Count"))), m)));
roiManager("Measure");
print("\n[Nucleus Measurement Report]");
print("Measurements: "+nResults+" Datapoints corresponding to "+m+" Nuclear ROIs");
showStatus("Generating Histograms...");
// Unmerged Nuclear Size Histogram Export
run("Distribution...", "parameter=Area or="+bins+" and=0-0");
histogram2 = directoryHistogram+"/"+replace(File.getName(RAWimage), ".","_")+"_Nuclear_Size_Histogram.png";
if (!File.exists(histogram2))
{
selectImage("Area Distribution");
saveAs(".png", histogram2);
}
// Unmerged Nuclear Size Table Export
resultFile2 = directoryData+"/"+replace(File.getName(RAWimage), ".","_")+"_Nuclear_Size.csv";
if (!File.exists(resultFile2))
{
selectWindow("Results");
saveAs("Results", resultFile2);
}
// ------- Intermission - Manual ROI Screening ---------------------------------------------------------
close('*');
showStatus("Manual ROI Screening");
open(DAPIimage);
roiManager("Show All without labels");
selectWindow("ROI Manager");
waitForUser("Please maually screen ROIs\nOnce complete, click OK.");
n = countROIs('C'); // Recount Cells
m = roiManager("count") - n;
// ------- Phase Five - Outline Exporting --------------------------------------------------------------
// ROI Export - Unmerged
roiFile1 = directoryROIs+"/"+replace(File.getName(RAWimage), ".","_")+"_ROIs.zip";
if (!File.exists(roiFile1))
{
roiManager("Save", roiFile1);
}
deleteList = newArray();
imageWidth = getWidth();
imageHeight = getHeight();
topLimit = limitSize;
bottomLimit = imageHeight - limitSize;
leftLimit = limitSize;
rightLimit = imageWidth - limitSize;
run("Text Window...", "name=[Outline] width=100 height=50 monospaced");
print("[Outline]","\\Update:");
print("[Outline]", "FISH-QUANT\t");
print("[Outline]", "\nFile-version\t");
print("[Outline]", "\nRESULTS OF SPOT DETECTION PERFORMED ON\t");
print("[Outline]", "\nCOMMENT Automated outline definition (batch or quick-save)");
print("[Outline]", "\nIMG_Raw\t"+File.getName(RAWimage));
print("[Outline]", "\nIMG_Filtered\t");
print("[Outline]", "\nIMG_DAPI\t"+File.getName(DAPIimage));
print("[Outline]", "\nIMG_TS_label\t");
print("[Outline]", "\nFILE_settings");
print("[Outline]", "\nPARAMETERS");
print("[Outline]", "\nPix-XY\tPix-Z\tRI\tEx\tEm\tNA\tType");
print("[Outline]", "\n-\t-\t-\t-\t-\t-\t-");
for (i = 0; i < n; i++)
{
x_cell = newArray();
y_cell = newArray();
showStatus("Pairing ROIs...");
showProgress(i, n-1);
roiManager("Select", i);
roiManager("Set Line Width", 4);
getSelectionCoordinates(x_cell, y_cell);
nuclearIndex = newArray();
if (neg(x_cell, leftLimit, rightLimit) && neg(y_cell, topLimit, bottomLimit))
{
print("[Outline]", "\nCELL_START\t"+call("ij.plugin.frame.RoiManager.getName", i));
print("[Outline]", "\nX_POS\t"+tsv(x_cell));
print("[Outline]", "\nY_POS\t"+tsv(y_cell));
print("[Outline]", "\nZ_POS\t");
print("[Outline]", "\nCELL_END");
for (j = 0; j < m; j++)
{
x_nucleus = newArray();
y_nucleus = newArray();
k = n+j;
roiManager("Select", newArray(i,k));
roiManager("AND");
if ((i!=k)&&(selectionType>-1))
{
roiManager("Select", k);
getSelectionCoordinates(x_nucleus, y_nucleus);
if (neg(x_nucleus, leftLimit, rightLimit) && neg(y_nucleus, topLimit, bottomLimit))
{
nuclearIndex = append(nuclearIndex,k);
}
}
}
if (nuclearIndex.length == 1)
{
roiManager("Select", nuclearIndex[0]);
roiManager("Rename", "Single_"+call("ij.plugin.frame.RoiManager.getName", i)+"_Nucleus");
getSelectionCoordinates(x_nucleus, y_nucleus);
print("[Outline]", "\nNucleus_START\t"+call("ij.plugin.frame.RoiManager.getName", nuclearIndex[0]));
print("[Outline]", "\nX_POS\t"+tsv(x_nucleus));
print("[Outline]", "\nY_POS\t"+tsv(y_nucleus));
print("[Outline]", "\nZ_POS\t\t\t");
print("[Outline]", "\nNucleus_END");
}
else if (nuclearIndex.length == 2)
{
// Merging Two Nuclei
roiManager("Select", nuclearIndex[0]);
getSelectionCoordinates(xa, ya);
roiManager("Select", nuclearIndex[1]);
getSelectionCoordinates(xb, yb);
arr = mergeROIs(xa,ya,xb,yb);
mergex = newArray(xa.length+xb.length+2);
mergey = newArray(ya.length+yb.length+2);
xbNew = cycle(xb,arr[5]);
ybNew = cycle(yb,arr[5]);
for (v = 0; v < arr[2]; v++)
{
mergex[v] = xa[v];
mergey[v] = ya[v];
}
for (v = 0; v < xbNew.length; v++)
{
mergex[arr[2]+v] = xbNew[v];
mergey[arr[2]+v] = ybNew[v];
}
mergex[arr[2]+xbNew.length] = mergex[arr[2]];
mergey[arr[2]+ybNew.length] = mergey[arr[2]];
for(v = 0; v < (xa.length - arr[2]); v++)
{
mergex[arr[2]+xbNew.length+1+v] = xa[arr[2]-1+v];
mergey[arr[2]+ybNew.length+1+v] = ya[arr[2]-1+v];
}
mergex[xb.length+xa.length+1] = xa[xa.length-1];
mergey[xb.length+xa.length+1] = ya[xa.length-1];
roiManager("Select", nuclearIndex[0]);
makeSelection("trace", mergex, mergey);
roiManager("Update");
roiManager("Rename", "Merged_"+call("ij.plugin.frame.RoiManager.getName", i)+"_Nucleus");
roiManager("Set Color", "magenta");
roiManager("Set Line Width", 2);
deleteList = append(deleteList, nuclearIndex[1]);
print("[Outline]", "\nNucleus_START\t"+call("ij.plugin.frame.RoiManager.getName", nuclearIndex[0]));
print("[Outline]", "\nX_POS\t"+tsv(mergex));
print("[Outline]", "\nY_POS\t"+tsv(mergey));
print("[Outline]", "\nZ_POS\t\t\t");
print("[Outline]", "\nNucleus_END");
}
}
else
{
// Edge Cell Markup
roiManager("Set Color", "red");
roiManager("Set Line Width", 4);
deleteList = append(deleteList, i);
}
}
for (r = 0; r < roiManager("Count"); r++)
{
// Exclusion Cleanup
showStatus("Deleting Excluded ROIs...");
roiManager("Select", r);
if (startsWith(call("ij.plugin.frame.RoiManager.getName", r),'N'))
{
deleteList = append(deleteList, r);
}
}
print("[Outline]", "\n");
image = getTitle;
// Delete Redundant and Excluded ROIs
roiManager("Select", deleteList);
roiManager("Delete");
// ROI Export - Merged
roiFile2 = directoryROIs+"/_FILTERED_"+replace(File.getName(RAWimage), ".","_")+"_ROIs.zip";
if (!File.exists(roiFile2))
{
roiManager("Save", roiFile2);
}
run("Clear Results");
n = countROIs('C'); // Recount Cells
m = roiManager("count") - n;
roiManager("Select",Array.reverse(Array.trim(Array.reverse(Array.getSequence(roiManager("Count"))), m)));
if (m > 0)
roiManager("Measure");
print("\n[Nucleus Pairing Report]");
print("Total Cells: " + n);
print("Cells - Single Nuclei: " + countROIs("S")+" ("+d2s((countROIs("S")/n*100),3)+"%)");
print("Cells - Merged Nuclei: " + countROIs("M")+" ("+d2s((countROIs("M")/n*100),3)+"%)");
// Merged Nuclear Size Histogram Export
run("Distribution...", "parameter=Area or="+bins+" and=0-0");
histogram3 = directoryHistogram+"/_FILTERED_"+replace(File.getName(RAWimage), ".","_")+"Nuclear_Size_Histogram.png";
if (!File.exists(histogram3))
{
selectImage("Area Distribution");
saveAs(".png", histogram3);
}
// Merged Nuclear Size Table Export
resultFile3 = directoryData+"/_FILTERED_"+replace(File.getName(RAWimage), ".","_")+"_Nuclear_Size.csv";
if (!File.exists(resultFile3))
{
selectWindow("Results");
saveAs("Results", resultFile3);
}
// Export Outlines
outlineFile = directoryMain+"/"+replace(File.getName(RAWimage), ".","_")+"_Outline.txt";
if (!File.exists(outlineFile))
{
selectWindow("Outline");
saveAs("Text", outlineFile);
}
// ------- Final Steps - Filtered Output Generation --------------------------------------------------------------
n = countROIs('C'); // Recount Cells
m = roiManager("count") - n;
run("Clear Results");
roiManager("Select", Array.getSequence(n));
selectImage(image);
roiManager("Measure");
showStatus("Generating Histograms...");
// Filtered Cell Size Histogram Export
run("Distribution...", "parameter=Area or="+bins+" and=0-0");
FILhistogram1a = directoryHistogram+"/_FILTERED_"+replace(File.getName(RAWimage), ".","_")+"_Cell_Size_Histogram.png";
if (!File.exists(FILhistogram1a))
{
selectImage("Area Distribution");
saveAs(".png", FILhistogram1a);
}
// Filtered Cell Length Histogram Export
run("Distribution...", "parameter=Major or="+bins+" and=0-0");
FILhistogram1b = directoryHistogram+"/_FILTERED_"+replace(File.getName(RAWimage), ".","_")+"_Cell_Length_Histogram.png";
if (!File.exists(FILhistogram1b))
{
selectImage("Major Distribution");
saveAs(".png", FILhistogram1b);
}
// Filtered Cell Width Histogram Export
run("Distribution...", "parameter=Minor or="+bins+" and=0-0");
FILhistogram1c = directoryHistogram+"/_FILTERED_"+replace(File.getName(RAWimage), ".","_")+"_Cell_Width_Histogram.png";
if (!File.exists(FILhistogram1c))
{
selectImage("Minor Distribution");
saveAs(".png", FILhistogram1c);
}
// Filtered Cell Size File Export
FILresultFile = directoryData+"/_FILTERED_"+replace(File.getName(RAWimage), ".","_")+"_Cell_Size.csv";
if (!File.exists(FILresultFile))
{
selectWindow("Results");
saveAs("Results", FILresultFile);
}
selectWindow(replace(File.getName(RAWimage), ".","_")+"_Outline.txt");
run("Close");
roiManager("Reset");
close('*');
showStatus("Producing Overlays...");
setBatchMode("hide");
// Overlay Production - Axis Annotation
open(AFPfocus);
run("RGB Color");
setLineWidth(2);
for(i = 0; i < nResults; i++)
{
showProgress(i, nResults-1);
x = getResult('X',i);
y = getResult('Y',i);
d = getResult("Major",i);
a = getResult("Angle",i)*PI/180;
setColor("blue");
drawLine(x+(d/2)*cos(a),y-(d/2)*sin(a),x-(d/2)*cos(a),y+(d/2)*sin(a));
d = getResult("Minor",i);
a = a+PI/2;
setColor("red");
drawLine(x+(d/2)*cos(a),y-(d/2)*sin(a),x-(d/2)*cos(a),y+(d/2)*sin(a));
}
// Axis Annotation Overlay Export
overlay1 = directoryOverlays+"/IMG0_"+replace(File.getName(RAWimage), ".","_")+"_Axis.tif";
if (!File.exists(overlay1))
{
saveAs(".tiff", overlay1);
}
roiManager("Reset");
close('*');
showStatus("Producing Overlays...");
open(DAPIfocus);
run("RGB Color");
roiManager("Open", roiFile2);
n = countROIs('C');
roiManager("Select", Array.getSequence(n));
roiManager("Delete");
roiManager("Deselect");
run("From ROI Manager");
run("Flatten", "stack");
// Nuclear ROI Overlay on DAPI Export
overlay2 = directoryOverlays+"/IMG1_"+replace(File.getName(RAWimage), ".","_")+"_Nuclear_ROIs_DAPI.tif";
if (!File.exists(overlay2))
{
saveAs(".tiff", overlay2);
}
roiManager("Reset");
close('*');
showStatus("Producing Overlays...");
open(RAWimage);
run("RGB Color");
roiManager("Open", roiFile2);
n = countROIs('C');
m = roiManager("count") - n;
roiManager("Select",Array.reverse(Array.trim(Array.reverse(Array.getSequence(roiManager("Count"))), m)));
roiManager("Delete");
roiManager("Deselect");
run("From ROI Manager");
run("Flatten", "stack");
// Cell ROI Overlay on RAW Export
overlay3 = directoryOverlays+"/IMG2_"+replace(File.getName(RAWimage), ".","_")+"_Cell_ROIs_RAW.tif";
if (!File.exists(overlay3))
{
saveAs(".tiff", overlay3);
}
roiManager("Reset");
close('*');
showStatus("Producing Overlays...");
open(AFPfocus);
run("RGB Color");
roiManager("Open", roiFile2);
n = countROIs('C');
m = roiManager("count") - n;
roiManager("Select",Array.reverse(Array.trim(Array.reverse(Array.getSequence(roiManager("Count"))), m)));
roiManager("Delete");
roiManager("Deselect");
run("From ROI Manager");
run("Flatten", "stack");
// Cell ROI Overlay on AFP Export
overlay4 = directoryOverlays+"/IMG3_"+replace(File.getName(RAWimage), ".","_")+"_Cell_ROIs_AFP.tif";
if (!File.exists(overlay4))
{
saveAs(".tiff", overlay4);
}
t1 = getTime();
tf = t1 - t0;
print("\n[Runtime Report]");
print("Total Runtime: " + d2s(tf/1000,2) + " seconds");
// Log File Export
logFile = directoryMain+"/"+logID+"_runLog.txt";
if (!File.exists(logFile))
{
selectWindow("Log");
saveAs("Text", logFile);
}
cleanAll();
waitForUser("Segmentation and Analysis are Complete\nPlease review files in output directory.");
}
// ------- Function Bank ----------------------------------------------------------------------------------------
// Clean Up Function
function cleanAll()
{
close('*');
run("Clear Results");
roiManager("Reset");
print("\\Clear");
}
// Append to Array Function
function append(arr, value)
{
arr2 = newArray(arr.length+1);
for (i=0; i upper)
qual = false;
}
return qual;
}
// Cycles Values to Index
function cycle(arr, index)
{
n = arr.length;
cycledArray = newArray(n);
if (index < n)
{
for (i = index; i < n; i++)
cycledArray[i-index] = arr[i];
for (i = 0; i < index; i++)
cycledArray[n+i-index] = arr[i];
}
return cycledArray;
}
// Find Bridging Coordinates
function mergeROIs(x1,y1,x2,y2)
{
index1 = 0;
index2 = 0;
bestDistance = 50000; // Some arbitrary large number
result = newArray(7);
if ((x1.length == y1.length) && (x2.length == y2.length))
{
for (i = 0; i < x1.length; i++)
{
for (j = 0; j < x2.length; j++)
{
distance = sqrt(pow(x1[i]-x2[j],2)+pow(y1[i]-y2[j],2));
if (distance < bestDistance)
{
bestDistance = distance;
result[0] = x1[i]; // [A] Bridge Point X
result[1] = y1[i]; // [A] Bridge Point Y
result[2] = i; // [A] Bridge Point index
result[3] = x2[j]; // [B] Bridge Point X
result[4] = y2[j]; // [B] Bridge Point Y
result[5] = j; // [B] Bridge Point index
result[6] = bestDistance; // {A,B] Distance between Bridge Points
}
}
}
}
return result;
}
// Count ROIs with Matching First Letter
function countROIs(firstLetter)
{
ping = NaN;
n = roiManager("Count");
for (i = 0; i < n; i++)
{
if (startsWith(call("ij.plugin.frame.RoiManager.getName", i),firstLetter))
{
if (isNaN(ping))
ping = 1;
else
ping++;
}
}
return ping;
}
// Debug Intervene Function - Add inbetween lines to Debug
function intervene()
{
waitForUser("Macro has been halted for debugging.");
}