// This makes the pop up at the beginning with instructions // Unordered lists, headers, and text modifiers showMessage("1/1", "" + "

General Instructions

" + "

Install featureJ derivatives:

Image Folder:

"+""+""+"

General Comments:

" + ""); // All of the images are sorted within these following loops //For automatically defining the ROI, we have two variable that can be easily changed to any number user wants, which are enlarge size and reduce size of the ROI enlargeROI = 60; reduceROI = -90; run("Set Measurements...", "area mean integrated redirect=None decimal=5"); /*Dialog.create("Selection of Type of Study"); Dialog.addChoice("Type of Study",newArray("Study with the Whole Image","Study with the Graph","Study by Drawing your own Graph","Study with Two Tubules Channels")); Dialog.show();*/ //ImageSort section //---------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------- //Arrays made for later use. stringy = getDirectory("Choose a Directory"); FileList = getFileList(stringy); FutureList = getFileList(stringy); tempArray = getFileList(stringy); StringyList = getFileList(stringy); q = FileList.length; //loop that turns letters to numbers for (k1 = 0; k1 < q; k1++) { a = split(FileList[k1], "."); FutureList[k1] = parseInt(a[0]); tempArray[k1] = a[1]; } //loop that sorts array for (i = 0; i < q; i++) { for (j = i + 1; j < q; j++) { if (FutureList[i] > FutureList[j]) { temp = FutureList[i]; FutureList[i] = FutureList[j]; FutureList[j] = temp; } } } //loop that turns numbers back to letters for (p = 0; p < q; p++) { number = d2s(FutureList[p], 0); StringyList[p] = number + "." + tempArray[p]; } tubuleaverage = newArray(q); //stores image Mean pixel inten tubulesortaverage = newArray(q); //to be sorted j = 1; //counter variable for result sorting to be done at the end setBackgroundColor(0, 255, 255); setForegroundColor(253, 253, 253); //---------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------- //======================== //========================= //USER INPUT //obtain color of tubules tubulecolor = getString("enter the color of your tubules(r,b,g): //", "r"); //=========================== //============================ //loop opens images and tracks down their individual statistics //=========================================================== //this loop is for tubule intensities for (i = 0; i < q; i++) { setBackgroundColor(0, 255, 255); setForegroundColor(253, 253, 253); open(stringy + StringyList[i]); wait(25); run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); rename("image2"); selectWindow("image2"); run("Split Channels"); if (tubulecolor == "r") { close(); close(); } if (tubulecolor == "g") { close(); close("\\Others"); } if (tubulecolor == "b") { close("\\Others"); } getRawStatistics(nPixels, Mean, min, max, std, histogram); tubuleaverage[i] = Mean; tubulesortaverage[i] = Mean; close(); } //values are then searched for the max. highestvalue = tubulesortaverage[q - 1]; mediantubulevalue = tubulesortaverage[floor(q / 2)]; print("Highest value of tubules " + highestvalue); print("Median value of tubules " + mediantubulevalue); Myhighindex = 0; //this loop finds the index of the highest value for tubules //and the index for the median value for the tubules for (i = 0; i < q; i++) { if (tubuleaverage[i] == highestvalue) { Myhighindex = i; } if (tubuleaverage[i] == mediantubulevalue) { MyMedTubuleIndex = i; } } absolutehigh = Myhighindex; //prints values just to check in the log Array.print(StringyList); Dialog.create("Select method of identifying reference image for defining tubule detection parameters"); Dialog.addCheckbox(" Highest tubule channel signal intensity (default) ",true); Dialog.addCheckbox(" Medium tubule channel signal intensity",false); Dialog.show(); highindex = Dialog.getCheckbox(); medindex = Dialog.getCheckbox(); if (medindex) Myhighindex = MyMedTubuleIndex; //purpose: Obtain Tubule sensitivity value //-------------------------- //--------------------------- //we open the medium tubule image. open(stringy + StringyList[Myhighindex]); wait(25); run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); rename("image2"); selectWindow("image2"); run("Split Channels"); if (tubulecolor == "r") { close(); close(); } if (tubulecolor == "g") { close(); close("\\Others"); } if (tubulecolor == "b") { close("\\Others"); } rename("image2"); selectWindow("image2"); wait(25); run("Duplicate...", "title=GFP"); wait(25); selectWindow("GFP"); wait(25); run("Duplicate...", "title=GFP2"); wait(25); selectWindow("GFP"); close(); selectWindow("GFP2"); run("Duplicate...", "title=GFP3"); wait(25); selectWindow("GFP3"); getRawStatistics(nPixels, Mean, min, max, std, histogram); run("Close"); wait(25); selectWindow("GFP2"); //user selected area in order to input tubule detection parameters. makeRectangle(0, 0, 400, 400); waitForUser("Please place this box over an area with representative tubules intensities you want to detect, you can change its size if you wish, Click OK when done."); run("Duplicate...", "title=faintTubules"); close("\\Others"); roiManager("reset"); //--------------------------------------------------------------- //-------------------------------------------------------------- //user input repeating while loop to find THRESHY! //-------------------------------------------------------------- //initial tubule parameters Threshy = 5; MinTubuleLength = 1; Continue = false; //while loop condition while (Continue == false) { //---------------------------------------------------------- //this is to destroy all of the holes, holes are thresholded and created into an ROI //---------------------------------------------------------- //---------------------------------------------------------- wait(25); run("Duplicate...", "title=HoleKiller"); wait(25); getRawStatistics(nPixels, Mean, min, max, std, histogram); getDimensions(width, height, channels, slices, frames); run("Threshold..."); setAutoThreshold("Default dark"); setThreshold(0, 1.25 * Mean); setOption("BlackBackground", false); run("Convert to Mask"); run("Create Selection"); if (selectionType() != -1) { roiManager("Add"); //roi of holes BoxHoles = roiManager("count") - 1; } else { BoxHoles = -1; } selectWindow("HoleKiller"); close(); //----------------------------------------------------- //------------------------------------------------------- smooth = 0.4; //calculates derivitive in x direction run("FeatureJ Derivatives", "x-order=1 y-order=0 z-order=0 smoothing=smooth"); rename("GradientX"); wait(25); //Zero's out the holes area //Because we are dealing with a 32 bit image, its kind of difficult // to simply set a pixel to a value. As a result, I guess a value // and check to see what value it corresponds to on the derivitive image //I then loop until that value converges to a small number, and use this //value to essentially zero the holes. if (BoxHoles > -1) { roiManager("Select", BoxHoles); getRawStatistics(nPixels, Mean, min, max, std, histogram); getDimensions(width, height, channels, slices, frames); xx = 128; setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); makeRectangle(0, 0, 1, 1); run("Fill", "slice"); while (abs(getPixel(0, 0)) > 0.5) { setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); makeRectangle(0, 0, 1, 1); run("Fill", "slice"); if (getPixel(0, 0) > 0) { xx = xx - 1; } else { xx = xx + 1; } counter = counter + 1; } setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); roiManager("Select", BoxHoles); wait(25); run("Fill", "slice"); } //Here, the gradient image is inverted using nested for loops. //This is done to make thresholding easier later on. getDimensions(width, height, channels, slices, frames); for (ii = 0; ii < width; ii++) { for (jj = 0; jj < height; jj++) { currentvalue = getPixel(ii, jj); setPixel(ii, jj, 1 / currentvalue); } } wait(25); //This is the thresholding step getRawStatistics(nPixels, Mean, min, max, std, histogram); run("Threshold..."); setAutoThreshold("Default dark"); setThreshold(-1 / Threshy, 1 / Threshy); wait(50); run("Convert to Mask"); wait(50); run("Make Binary"); wait(50); run("Create Selection"); if (selectionType() != -1) { roiManager("Add"); //roi[0]Tubules in X BoxTubulesInX = roiManager("count") - 1; } else { BoxTubulesInX = -1; } selectWindow("GradientX"); close(); //The process is repeated for the y-direction. run("FeatureJ Derivatives", "x-order=0 y-order=1 z-order=0 smoothing=smooth"); wait(25); rename("GradientY"); wait(25); if (BoxHoles > -1) { roiManager("Select", BoxHoles); getRawStatistics(nPixels, Mean, min, max, std, histogram); getDimensions(width, height, channels, slices, frames); xx = 128; setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); makeRectangle(0, 0, 1, 1); run("Fill", "slice"); while (abs(getPixel(0, 0)) > 0.5) { setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); makeRectangle(0, 0, 1, 1); run("Fill", "slice"); if (getPixel(0, 0) > 0) { xx = xx - 1; } else { xx = xx + 1; } counter = counter + 1; } setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); roiManager("Select", BoxHoles); wait(25); run("Fill", "slice"); } getDimensions(width, height, channels, slices, frames); for (ii = 0; ii < width; ii++) { for (jj = 0; jj < height; jj++) { currentvalue = getPixel(ii, jj); setPixel(ii, jj, 1 / currentvalue); } } wait(25); run("Threshold..."); setAutoThreshold("Default dark"); setThreshold(-1 / Threshy, 1 / Threshy); run("Convert to Mask"); wait(50); run("Make Binary"); wait(50); run("Create Selection"); if (selectionType() != -1) { roiManager("Add"); //roi[1]Tubules in Y BoxTubulesInY = roiManager("count") - 1; } else { BoxTubulesInY = -1; } selectWindow("GradientY"); close(); selectWindow("faintTubules"); getDimensions(width, height, channels, slices, frames); newImage("Skeleton", "8-bit white", width, height, 1); setForegroundColor(0, 0, 0); setBackgroundColor(0, 0, 0); //Now, we take the detection from the x and y directions and overlay them if (BoxTubulesInX > -1 && BoxTubulesInY > -1) { roiManager("Select", BoxTubulesInX); run("Fill", "slice"); roiManager("Select", BoxTubulesInY); run("Fill", "slice"); } run("Create Selection"); //this enlarge step is done to clear holes in the center if any. run("Enlarge...", "enlarge=1"); run("Enlarge...", "enlarge=-1"); if (selectionType() != -1) { roiManager("Add"); //roi[2] blob tubules BoxBlobTubules = roiManager("count") - 1; } else { BoxBlobTubules = -1; } selectWindow("Skeleton"); if (BoxBlobTubules > -1) { roiManager("Select", BoxBlobTubules); run("Fill", "slice"); } //Here, the blobs are skeletonized and then trimmed based on the minimum tubule length run("Make Binary"); run("Analyze Particles...", "size=MinTubuleLength show=Masks"); //gets rid of tubules of length size run("Create Selection"); if (selectionType() != -1) { roiManager("Add"); //roi[3] skeletonized tubulez BoxSkeletonizedTubules = roiManager("count") - 1; } else { BoxSkeletonizedTubules = -1; } selectWindow("Skeleton"); close(); wait(25); selectWindow("faintTubules"); //Here the skeletonized tubules are overlayed to the image close("\\Others"); run("Duplicate...", "title=test"); selectWindow("faintTubules"); if (BoxSkeletonizedTubules > -1) { wait(500); roiManager("Select", BoxSkeletonizedTubules); wait(500); selectWindow("test"); wait(500); selectWindow("faintTubules"); wait(500); selectWindow("test"); wait(500); selectWindow("faintTubules"); } //Here the user input for the tubule detection parameters occurs. Dialog.create("Tubule Detection Parameters"); Dialog.addNumber("Tubule Detection Sensitivity, (larger # = less sensitive)", Threshy); Dialog.addNumber("Minimum Tubule Length [pixel]", MinTubuleLength); Dialog.addCheckbox("Check to accept settings", false); Dialog.show(); Threshy = Dialog.getNumber(); MinTubuleLength = Dialog.getNumber();; Continue = Dialog.getCheckbox(); print("Threshy is now " + Threshy); if (BoxSkeletonizedTubules > 0) { roiManager("select", BoxSkeletonizedTubules); roiManager("Delete"); } roiManager("reset"); } close("\\Others"); close(); //-------------------------------------------------------------- //-------------------------------------------------------------- //-------------------------------------------------------------- //-------------------------------------------------------------- //Now that the parameters are all defined, the program will loop through and analyze all the images. run("Set Measurements...", "area mean integrated redirect=None decimal=5"); //makes checkpictures folder myDir = stringy + "Traced Images" + File.separator; File.makeDirectory(myDir); if (!File.exists(myDir)) exit("Unable to create directory"); j = 1; //counter variable for result setBackgroundColor(0, 255, 255); setForegroundColor(253, 253, 253); for (i = 0; i < q; i++) { setBackgroundColor(0, 255, 255); setForegroundColor(253, 253, 253); open(stringy + StringyList[i]); wait(25); run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); rename("image2"); selectWindow("image2"); run("Split Channels"); if (tubulecolor == "r") { close(); close(); } if (tubulecolor == "g") { close(); close("\\Others"); } if (tubulecolor == "b") { close("\\Others"); } rename("image2"); selectWindow("image2"); selectWindow("image2"); //---------------------------------------------------------- //this is to destroy all of the holes //---------------------------------------------------------- //---------------------------------------------------------- wait(25); run("Duplicate...", "title=HoleKiller"); wait(25); getRawStatistics(nPixels, Mean, min, max, std, histogram); getDimensions(width, height, channels, slices, frames); run("Threshold..."); setAutoThreshold("Default dark"); setThreshold(0, 1.25 * Mean); setOption("BlackBackground", false); run("Convert to Mask"); run("Create Selection"); if (selectionType() != -1) { roiManager("Add"); //roi[2] holes Holes = roiManager("count") - 1; } else { Holes = -1; } selectWindow("HoleKiller"); close(); //----------------------------------------------------- //------------------------------------------------------- run("FeatureJ Derivatives", "x-order=1 y-order=0 z-order=0 smoothing=smooth"); rename("GradientX"); wait(25); //Zero's out the holes area // if (Holes > -1) { roiManager("Select", Holes); getRawStatistics(nPixels, Mean, min, max, std, histogram); getDimensions(width, height, channels, slices, frames); xx = 128; setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); makeRectangle(0, 0, 1, 1); run("Fill", "slice"); while (abs(getPixel(0, 0)) > 0.5) { setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); makeRectangle(0, 0, 1, 1); run("Fill", "slice"); if (getPixel(0, 0) > 0) { xx = xx - 1; } else { xx = xx + 1; } counter = counter + 1; } setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); roiManager("Select", Holes); wait(25); run("Fill", "slice"); } getDimensions(width, height, channels, slices, frames); for (ii = 0; ii < width; ii++) { for (jj = 0; jj < height; jj++) { currentvalue = getPixel(ii, jj); setPixel(ii, jj, 1 / currentvalue); } } getRawStatistics(nPixels, Mean, min, max, std, histogram); run("Threshold..."); setAutoThreshold("Default dark"); setThreshold(-1 / Threshy, 1 / Threshy); wait(50); //run("NaN Background"); run("Convert to Mask"); wait(50); run("Make Binary"); wait(50); //setForegroundColor(0, 0, 0); //setBackgroundColor(0, 0, 0); //setOption("BlackBackground", false); run("Create Selection"); //checks to see if actual selection exist if (selectionType() != -1) { roiManager("Add"); //roi[3]Tubules in X TubulesInX = roiManager("count") - 1; } else { TubulesInX = -1; } selectWindow("GradientX"); close(); //selectWindow("GFP2-iter13"); run("FeatureJ Derivatives", "x-order=0 y-order=1 z-order=0 smoothing=smooth"); rename("GradientY"); wait(25); if (Holes > -1) { roiManager("Select", Holes); getRawStatistics(nPixels, Mean, min, max, std, histogram); getDimensions(width, height, channels, slices, frames); xx = 128; setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); makeRectangle(0, 0, 1, 1); run("Fill", "slice"); while (abs(getPixel(0, 0)) > 0.5) { setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); makeRectangle(0, 0, 1, 1); run("Fill", "slice"); if (getPixel(0, 0) > 0) { xx = xx - 1; } else { xx = xx + 1; } counter = counter + 1; } setForegroundColor(xx, xx, xx); setBackgroundColor(xx, xx, xx); roiManager("Select", Holes); wait(25); run("Fill", "slice"); } getDimensions(width, height, channels, slices, frames); for (ii = 0; ii < width; ii++) { for (jj = 0; jj < height; jj++) { currentvalue = getPixel(ii, jj); setPixel(ii, jj, 1 / currentvalue); } } run("Threshold..."); setAutoThreshold("Default dark"); setThreshold(-1 / Threshy, 1 / Threshy); run("Convert to Mask"); //run("NaN Background"); wait(50); //setForegroundColor(0, 0, 0); //setBackgroundColor(0, 0, 0); //setOption("BlackBackground", false); run("Make Binary"); wait(50); run("Create Selection"); if (selectionType() != -1) { roiManager("Add"); //roi[4]Tubules in Y TubulesInY = roiManager("count") - 1; } else { TubulesInY = -1; } selectWindow("GradientY"); close(); //selectWindow("GFP2-iter13"); //close(); selectWindow("image2"); getDimensions(width, height, channels, slices, frames); newImage("Skeleton", "8-bit white", width, height, 1); setForegroundColor(0, 0, 0); setBackgroundColor(0, 0, 0); if (TubulesInX > -1 && TubulesInY > -1) { roiManager("Select", TubulesInX); run("Fill", "slice"); wait(25); roiManager("Select", TubulesInY); run("Fill", "slice"); wait(25); run("Create Selection"); run("Enlarge...", "enlarge=1"); wait(25); run("Enlarge...", "enlarge=-1"); roiManager("Add"); //roi[5] blob tubules BlobTubules = roiManager("count") - 1; } else { BlobTubules = -1; } selectWindow("Skeleton"); if (BlobTubules > -1) { roiManager("Select", BlobTubules); wait(25); run("Fill", "slice"); } run("Make Binary"); wait(25); //roiManager("select",GraftAreaInSmallWindow); //run("Enlarge...", "enlarge=-1"); //setForegroundColor(255, 255, 255); //setBackgroundColor(255, 255, 255); //run("Clear Outside"); run("Analyze Particles...", "size=MinTubuleLength show=Masks"); run("Create Selection"); run("Measure"); if (selectionType() != -1) { roiManager("Add"); //roi[6] skeletonized tubulez wait(25); SkeletonizedTubules = roiManager("count") - 1; } else { SkeletonizedTubules = -1; } setResult("Image Name", j - 1, "Tubule" + StringyList[i]); j = j + 1; //drawing pictures, creates the images in traced images folder. //------------------------------------------------------------ selectWindow("image2"); run("Select None"); Coolstring = split(StringyList[i], "."); run("Duplicate...", "title=blank"); wait(25); saveAs("Tiff", myDir + Coolstring[0] + "a.tif"); close(); run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); //drawing picture run("Line Width...", "line=1"); wait(25); if (SkeletonizedTubules > -1) { roiManager("Select", SkeletonizedTubules); run("RGB Color"); setForegroundColor(255, 255, 0); run("Draw"); } run("Save", "save=[" + myDir + Coolstring[0] + "b.tif" + "]"); run("Close"); wait(25); close("\\Others"); run("Close"); roiManager("reset"); } //Organizes tubule data sum = 0; counter = 0; for (i = 0; i < j - 1; i += 1) { Area = getResult("Area", i); setResult("TubuleLengthPerimage [pix]", i, Area); sum = sum + Area; if (Area != 0) counter = counter + 1; } setResult("Sum of Tubule Length Per Folder [pix]", 0, sum); setResult("Average Tubule Length Per Image [pix]", 0, sum / counter); setResult("Tubule detection sensitivity:", 0,Threshy); setResult("Minimum Tubule Length [Pix]",0,MinTubuleLength); folder = File.getName(stringy); name = folder + " Tracing Data Summary.csv"; saveAs("Results", stringy + name); wait(25); run("Clear Results"); // Headers, font color, and italics showMessage("1/1", "" + "

Analysis Complete

");