/* - 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 = "1.0"; // WEKA-FISH Pipeline Version macro "WEKA-FISH" { cleanAll(); showMessageWithCancel("WEKA-FISH Outliner "+WFv, "" +"
WEKA-FISH Outliner
" +"
Hauf Lab - Biocomplexity Institute 2018
" +"" +"
[Erod Keaton Baybay - erodb@vt.edu]
"); // Default Parameters limitSize = 5; // ------- Initialization I - File Designation ----------------------------------------------------------------------- showStatus("Initializing WEKA-FISH..."); run("Set Measurements...", "area centroid fit display redirect=None decimal=3"); showStatus("Initializing WEKA-FISH... [Raw Image]"); waitForUser("Please select a Raw Image (FISHRed)"); RAWimage = File.openDialog("Choose Raw Image"); showStatus("Initializing WEKA-FISH... [ROI File]"); waitForUser("Please select an unfiltered ROI zip file"); ROIzip = File.openDialog("Choose ROI File"); open(RAWimage); roiManager("Open",ROIzip); print("[Outliner]"); print("Image: "+RAWimage); 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"); print("[Outline]", "\nIMG_Filtered\t"); print("[Outline]", "\nIMG_DAPI\t"); 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-"); n = countROIs('C'); // Recount Cells m = roiManager("count") - n; 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"); 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))); 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)+"%)"); roiManager("Reset"); close('*'); waitForUser("Outline Generation Complete\n Please save Log and Outline file."); } // ------- 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]; result[1] = y1[i]; result[2] = i; result[3] = x2[j]; result[4] = y2[j]; result[5] = j; result[6] = bestDistance; } } } } 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."); }