//////////////////////////////////////////////////////////////// /* PIPSQUEAK! Perineuronal net Intensity Program for the Standardization and Quantification of ECM Analysis Written by John H. Harkness, PhD. >>> Contact: harknessjh@gmail.com >>> Copyright (C) 2016, John H. Harkness Washington State University, Vancouver Supported by: >>> Rewire Neuroscience (rewireneuroscience.com) >>> WSU Alcohol and Drug Abuse Research Program (ADARP) >>> The Translational Addiction Research Center (TARC) >>> NIH DA 033404 >>> Washington State Initiative Measure No. 171 Protocol based on Slaker, Harkness, and Sorg, 2016 >>> Special thanks to Megan Slaker, PhD >>> PLEASE CITE: Slaker, et al., 2016 (IN SUBMISSION) <<< */ //////////////////////////////////////////////////////////////// //Global variables var scale_size = 1.194; var scale_known = 1; var scale_pixel = 1; var scale_unit = "um"; var set_intensity_low_threshold = 1.165; var set_intensity_high_threshold = 5000; var set_low_particlesize = 70; var set_high_particlesize = 99999; var set_low_circularity = 0.02; var set_high_circularity = 1.00; var set_roi_enlargement_single = 6.00; var set_intensity_low_threshold_old = 1.165; var set_low_particlesize_old = 70; var set_high_particlesize_old = 99999; var set_count_low_threshold = 0.5; var set_count_high_threshold = 5000; var set_count_low_particlesize = 20; var set_count_high_particlesize = 100000; var set_count_low_circularity = 0.02; var set_count_high_circularity = 1.00; var first_image = 0; var second_image = 0; var series_name = 0; var subDir = 0; var first_suffix = 1; var second_suffix = 3; var merged_suffix = 2; var total_images = 3; var first_stain_type = "PV"; var DL1_set_intensity_low_threshold = 1.0; var DL1_set_intensity_high_threshold = 5000; var DL1_set_low_particlesize = 40; var DL1_set_high_particlesize = 1000; var DL1_set_low_circularity = 0.02; var DL1_set_high_circularity = 1.00; var DL1_set_roi_enlargement = -1.00; var SL1_set_intensity_low_threshold_old = 1.0; var SL1_set_low_particlesize_old = 40; var SL1_set_high_particlesize_old = 1000; //var DL1_set_intensity_low_threshold_old = 1.0; //var DL1_set_low_particlesize_old = 40; //var DL1_set_high_particlesize_old = 1000; var DL1_lower = 0; var second_stain_type = "WFA"; var DL2_set_intensity_low_threshold = 1.165; var DL2_set_intensity_high_threshold = 5000; var DL2_set_low_particlesize = 70; var DL2_set_high_particlesize = 99999; var DL2_set_low_circularity = 0.02; var DL2_set_high_circularity = 1.00; var DL2_set_roi_enlargement = 1.00; var SL2_set_intensity_low_threshold_old = 1.165; var SL2_set_low_particlesize_old = 70; var SL2_set_high_particlesize_old = 99999; //var DL2_set_intensity_low_threshold_old = 1.165; //var DL2_set_low_particlesize_old = 70; //var DL2_set_high_particlesize_old = 5000; var DL2_lower = 0; var lower = 0; var import_type = 0; var first_open = 0; var last_open = 0; var name = 0; var full_name = 0; var dir = 0; var first_time = 0; var save_location = 0; var pipsqueakCount = 1; var countCount = 1; var countDouble = 0; var first_open_double = 0; var last_open_double = 0; var subject_id = 0; /////////////////////////// macro "PIPSQUEAK" { if (pipsqueakCount==1){ ///call home tracking URL //UPDATE HERE (1/3)-> call_home_url = "http://jabstracts.org/PIPSQUEAK/call_home/v2-00/"; File.openUrlAsString(call_home_url); wait(200); print("\\Clear"); /// //UPDATE HERE (2/3)-> print("PIPSQUEAK! v2.01 Perineuronal net Intensity Program for the Standardization and Quantification of ECM Analysis."); print("\n"+"Copyright (C) 2016, John H. Harkness, PhD."); print("Protocol by Megan Slaker, PhD."); print("Lab of Barb Sorg, PhD., Washington State University, Vancouver"); print("\n"+"\n"+"Distance in pixels: "+scale_size+"\n"+"Known distance: "+scale_known+"\n"+"Pixel aspect ratio: "+scale_pixel+"\n"+"Unit of length: "+scale_unit); //UPDATE HERE (3/3)-> waitForUser("PIPSQUEAK version 2.01, Oct 5, 2016 \n \n 2.00 CHANGE LOG: Complete redesign for identification of double-labeled cells. \n Now, ROIs that are built during single-label identification will be maintained carried forward to the double-label step. \n Cells labeled by either single label are compared between labels and those with overlapping labels are identified as double labeled. \n This method accounts and corrects for partial overlap (removed if less that 80% overlap) and multiple overlap \n (two PV cells for one WFA cell). Pretty neat! One more thing, results output is improved in the Log Window. \n Now, each cell row contains subject, image name, and stain type information. Therefore, importing Log results into Excel \n is easier because you can use the 'sort data' tool to help remove unwanted rows.\n NOTE: Results from 2.00 and above should not be combined with earlier versions of PIPSQUEAK for statistical analysis. \n \n 2.01 CHANGE LOG: UI improvements in cell counting function."); wait(1000); pipsqueakCount = pipsqueakCount+1; } else { wait(50); } Dialog.create("Welcome."); items = newArray("Count labeled cells.", "Single label intensity analysis.", "Double label intensity analysis.", "->Change image scale settings."); Dialog.addRadioButtonGroup("What would you like to do?", items, 4, 1, " "); Dialog.show; choice = Dialog.getRadioButton; if (choice=="Count labeled cells.") { run("__sub_PIPSQUEAK_count"); } else { if (choice=="Single label intensity analysis.") { run("__sub_PIPSQUEAK_single"); } if (choice=="Double label intensity analysis.") { run("__sub_PIPSQUEAK_double"); } if (choice=="->Change image scale settings.") { Dialog.create("Settings 1 of 2"); Dialog.addMessage("**Image scale measurements (for both single and double label analysis)**"); Dialog.addNumber("Distance in pixels:", scale_size); Dialog.addNumber("Known distance:", scale_known); Dialog.addNumber("Pixel aspect ratio:", scale_pixel); Dialog.addString("Unit of length:", scale_unit); Dialog.addMessage(" "); Dialog.addMessage("---------------------------------------------------------------------"); Dialog.addMessage(" **ROI identification settings.**"); Dialog.addMessage("Adjustments will alter cell determination and MAY reduce identification specificity."); Dialog.addMessage("Proceed with caution: here be dragons."); //this can be improved in the future by adding a drop down menu that calls up set stain parameters. //!!need additional settings for double labeled analysis?!! Dialog.addMessage(" "); Dialog.addMessage("**Intensity measurements**"); //Dialog.addMessage(" "); Dialog.addNumber("Lower threshold multiplier:",set_intensity_low_threshold); Dialog.addNumber("Upper threshold limit:", set_intensity_high_threshold); Dialog.addNumber("Lower limit particle size:", set_low_particlesize); Dialog.addNumber("Upper limit particle size:", set_high_particlesize); Dialog.addNumber("Lower limit circularity:", set_low_circularity); Dialog.addNumber("Upper limit circularity:", set_high_circularity); Dialog.addNumber("ROI Enlargement (pixels):", set_roi_enlargement_single); Dialog.addMessage(" "); Dialog.addMessage(" "); Dialog.addMessage("**Cell count**"); //Dialog.addMessage(" "); Dialog.addNumber("Lower threshold multiplier:", set_count_low_threshold ); Dialog.addNumber("Upper threshold limit:", set_count_high_threshold); Dialog.addNumber("Lower limit particle size:", set_count_low_particlesize); Dialog.addNumber("Upper limit particle size:", set_count_high_particlesize); Dialog.addNumber("Lower limit circularity:", set_count_low_circularity); Dialog.addNumber("Upper limit circularity:", set_count_high_circularity); Dialog.show; scale_size = Dialog.getNumber(); scale_known = Dialog.getNumber();; scale_pixel = Dialog.getNumber();;; scale_unit = Dialog.getString(); set_intensity_low_threshold = Dialog.getNumber(); set_intensity_high_threshold = Dialog.getNumber();; set_low_particlesize = Dialog.getNumber();;; set_high_particlesize = Dialog.getNumber();;;; set_low_circularity = Dialog.getNumber();;;;; set_high_circularity = Dialog.getNumber();;;;;; set_roi_enlargement_single = Dialog.getNumber();;;;;;; set_count_low_threshold = Dialog.getNumber();;;;;;; set_count_high_threshold = Dialog.getNumber();;;;;;;; set_count_low_particlesize = Dialog.getNumber();;;;;;;;; set_count_high_particlesize = Dialog.getNumber();;;;;;;;;; set_count_low_circularity = Dialog.getNumber();;;;;;;;;;; set_count_high_circularity = Dialog.getNumber();;;;;;;;;;;; Dialog.create("Settings 1 of 2"); Dialog.addMessage("**Double-label Analysis**"); Dialog.addMessage(" "); Dialog.addMessage("Please enter the numbering suffixes of the image series you want to analyze in the space below."); Dialog.addMessage("eg: Exp42_SubA_example_1.tif and Exp42_SubA_example_3.tif = #1 and #3"); Dialog.addMessage(" "); Dialog.addNumber("First image (if possible, smaller volume stain):", first_suffix); Dialog.addNumber("Second image (if possible, larger volume stain):", second_suffix); Dialog.addNumber("Merged image:", merged_suffix); //Dialog.addNumber("Total number of stains plus composite in each subject series:", total_images); //REMOVED FOR NOW—SEE NOTE IN "__SUB_PIPSQUEAK_OPENNEXT_DOUBLE". Dialog.addMessage(" "); Dialog.addMessage("*First stain parameters*"); Dialog.addString("Stain type:", first_stain_type); Dialog.addNumber("Lower threshold multiplier:", DL1_set_intensity_low_threshold); Dialog.addNumber("Upper threshold limit:", DL1_set_intensity_high_threshold); Dialog.addNumber("Lower limit particle size:", DL1_set_low_particlesize); Dialog.addNumber("Upper limit particle size:", DL1_set_high_particlesize); Dialog.addNumber("Lower limit circularity:", DL1_set_low_circularity); Dialog.addNumber("Upper limit circularity:", DL1_set_high_circularity); Dialog.addNumber("ROI Enlargement (pixels):", DL1_set_roi_enlargement); Dialog.addMessage(" "); Dialog.addMessage("*Second stain parameters*"); Dialog.addString("Stain type:", second_stain_type); Dialog.addNumber("Lower threshold multiplier:", DL2_set_intensity_low_threshold); Dialog.addNumber("Upper threshold limit:", DL2_set_intensity_high_threshold); Dialog.addNumber("Lower limit particle size:", DL2_set_low_particlesize); Dialog.addNumber("Upper limit particle size:", DL2_set_high_particlesize); Dialog.addNumber("Lower limit circularity:", DL2_set_low_circularity); Dialog.addNumber("Upper limit circularity:", DL2_set_high_circularity); Dialog.addNumber("ROI Enlargement (pixels):", DL2_set_roi_enlargement); Dialog.show; first_suffix = Dialog.getNumber(); second_suffix = Dialog.getNumber();; merged_suffix = Dialog.getNumber();;; //total_images = Dialog.getNumber();;;; first_stain_type = Dialog.getString(); DL1_set_intensity_low_threshold = Dialog.getNumber();; DL1_set_intensity_high_threshold = Dialog.getNumber();;; DL1_set_low_particlesize = Dialog.getNumber();;;; DL1_set_high_particlesize = Dialog.getNumber();;;;; DL1_set_low_circularity = Dialog.getNumber();;;;;; DL1_set_high_circularity = Dialog.getNumber();;;;;;; DL1_set_roi_enlargement = Dialog.getNumber();;;;;;;; second_stain_type = Dialog.getString(); DL2_set_intensity_low_threshold = Dialog.getNumber();; DL2_set_intensity_high_threshold = Dialog.getNumber();;; DL2_set_low_particlesize = Dialog.getNumber();;;; DL2_set_high_particlesize = Dialog.getNumber();;;;; DL2_set_low_circularity = Dialog.getNumber();;;;;; DL2_set_high_circularity = Dialog.getNumber();;;;;;; DL2_set_roi_enlargement = Dialog.getNumber();;;;;;;; run("PIPSQUEAK"); } } } ////////////////////////// macro "__sub_PIPSQUEAK_count" { //count labeled cells import_type=4; if (countCount == 1) { Dialog.create("Count Labeled Cells."); items = newArray("Yes, continue.", "No. Go back."); Dialog.addRadioButtonGroup("For this analysis, you NEED TO SET THE CELL DETECTION PARAMETERS in Settings. Also, you need previously summed z-stacks. \n Do you have the correct settings and summed files ready?", items, 2, 1, "Yes, continue."); Dialog.show; choice = Dialog.getRadioButton; if (choice=="No. Go back.") { run("PIPSQUEAK"); } else { wait(50); } } else { wait(50); } countCount = countCount+1; Dialog.create("Cell Count"); items = newArray("Open image to count", "Adjust cell detection parameters", "Return to main menu"); Dialog.addRadioButtonGroup("What would you like to do?", items, 3, 1, "Open image to count"); Dialog.show; choice = Dialog.getRadioButton; if (choice=="Open image to count") { wait(100); } else { if (choice=="Return to main menu") { run("PIPSQUEAK"); } if (choice=="Adjust cell detection parameters") { Dialog.create("Settings"); Dialog.addMessage("**Cell count**"); //Dialog.addMessage(" "); Dialog.addNumber("Lower threshold multiplier:", set_count_low_threshold ); Dialog.addNumber("Upper threshold limit:", set_count_high_threshold); Dialog.addNumber("Lower limit particle size:", set_count_low_particlesize); Dialog.addNumber("Upper limit particle size:", set_count_high_particlesize); Dialog.addNumber("Lower limit circularity:", set_count_low_circularity); Dialog.addNumber("Upper limit circularity:", set_count_high_circularity); Dialog.show; set_count_low_threshold = Dialog.getNumber();;;;;;; set_count_high_threshold = Dialog.getNumber();;;;;;;; set_count_low_particlesize = Dialog.getNumber();;;;;;;;; set_count_high_particlesize = Dialog.getNumber();;;;;;;;;; set_count_low_circularity = Dialog.getNumber();;;;;;;;;;; set_count_high_circularity = Dialog.getNumber();;;;;;;;;;;; run("__sub_PIPSQUEAK_count"); } } open(); run("Set Measurements...", "area mean standard min redirect=None decimal=3"); run("Set Scale...", "distance=scale_size known=scale_known pixel=scale_pixel unit=&scale_unit global"); dir = getDirectory("image"); //print(dir); name = getTitle; full_name = getTitle; index = lastIndexOf(name, "."); if (index!=-1) name = substring(name, 0, index); //print("\n"+name+" loaded."); first_open = name; run("__sub_PIPSQUEAK_Background"); } ////////////////////////// macro "__sub_PIPSQUEAK_single" { // /* print("PIPSQUEAK! Perineuronal net Intensity Program for the Standardization and Quantification of ECM Analysis."); print("\n"+"Copyright (C) 2016, John H. Harkness, PhD."); print("Protocol by Megan Slaker, PhD."); print("Lab of Barb Sorg, PhD., Washington State University, Vancouver"); print("\n"+"Distance in pixels: "+scale_size+"\n"+"Known distance: "+scale_known+"\n"+"Pixel aspect ratio: "+scale_pixel+"\n"+"Unit of length: "+scale_unit); wait(1000); */ Dialog.create("Import Type"); // /*items = newArray("Semiautomated analysis of raw, non-summed, individual Tiffs", "Semiautomated analysis of summed Z-stacks", "Automatic analysis of summed Z-stacks","->Make summed image from z-stacks."); Dialog.addRadioButtonGroup("What type of file do you want to import?", items, 4, 1, "Semiautomated analysis of summed Z-stacks"); */ // items = newArray("Semiautomated analysis of raw, non-summed, individual Tiffs", "Semiautomated analysis of summed Z-stacks", "Automatic analysis of summed Z-stacks"); Dialog.addRadioButtonGroup("What type of file do you want to import?", items, 3, 1, "Semiautomated analysis of summed Z-stacks"); Dialog.show; choice = Dialog.getRadioButton; if (choice=="Semiautomated analysis of raw, non-summed, individual Tiffs") { import_type=1; run("__sub_PIPSQUEAK_Import"); } else { if (choice=="Semiautomated analysis of summed Z-stacks") { import_type=2; run("__sub_PIPSQUEAK_Import_Summed"); } if (choice=="Automatic analysis of summed Z-stacks") { import_type=3; run("__sub_PIPSQUEAK_Auto_Import_Summed"); } // /* if (choice=="->Make summed image from z-stacks.") { //Dialog.create("Stacks folder"); //Dialog.addMessage("Before using this function, please place z-stack images into a folder titled 'Stacks' within your experiment folder."); //Dialog.addMessage("ie, /Desktop/experiment folder/Stacks/image1... image20"); //Dialog.show(); run("__sub_PIPSQUEAK_z-project"); } */ } } ///////////////////////////// macro "__sub_PIPSQUEAK_Import" { // Importing stacks //import_type=1; run("Image Sequence...", "disable_global convert sort"); name = getTitle; dir = getDirectory("image"); selectWindow(name); run("Set Measurements...", "area mean standard min redirect=None decimal=3"); run("Z Project...", "projection=[Sum Slices]"); run("Set Scale...", "distance=scale_size known=scale_known pixel=scale_pixel unit=&scale_unit global"); full_name = "SUM_"+name; print("\n"+name+" loaded."); run("__sub_PIPSQUEAK_Background"); } ///////////////////////////// macro "__sub_PIPSQUEAK_Import_Summed" { // Importing image //import_type=2; open(); run("Set Measurements...", "area mean standard min redirect=None decimal=3"); run("Set Scale...", "distance=scale_size known=scale_known pixel=scale_pixel unit=&scale_unit global"); dir = getDirectory("image"); //print(dir); name = getTitle; full_name = getTitle; index = lastIndexOf(name, "."); if (index!=-1) name = substring(name, 0, index); print("\n"+name+" loaded."); first_open = name; run("__sub_PIPSQUEAK_Background"); } //////////////////////////////// macro "__sub_PIPSQUEAK_Auto_Import_Summed" { // Importing image //import_type=3; open(); run("Set Measurements...", "area mean standard min redirect=None decimal=3"); run("Set Scale...", "distance=scale_size known=scale_known pixel=scale_pixel unit=&scale_unit global"); dir = getDirectory("image"); name = getTitle; full_name = getTitle; index = lastIndexOf(name, "."); if (index!=-1) name = substring(name, 0, index); print("\n"+name+" loaded."); first_open = name; waitForUser("Please don't touch", "Please let the macro run without clicking windows. Disruption may cause the macro to stall."); run("__sub_PIPSQUEAK_Background"); } //////////////////////////////// macro "__sub_PIPSQUEAK_z-project" { //makes summed image from z-stack top_dir = getDirectory("Choose a Directory "); count = 1; listFiles(top_dir); function listFiles(top_dir) { list = getFileList(top_dir+"/.."); //child_list = getFileList(top_dir); parentlist = File.getParent(top_dir); for (i=0; i0) { roiManager("Delete"); } if (import_type==2) { selectWindow(name+".tif"); } if (import_type==1) { selectWindow("SUM_"+name); } roiManager("Show All"); roiManager("Show All with labels"); run("Clear Results"); wait(200); setAutoThreshold("Default dark"); run("Threshold..."); wait(200); setThreshold(lower*set_intensity_low_threshold, set_intensity_high_threshold); wait(200); makeRectangle(0, 0, 0, 0); run("Analyze Particles...", "size=set_low_particlesize-set_high_particlesize circularity=set_low_circularity-set_high_circularity clear include add"); wait(200); selectWindow("Threshold"); resetThreshold(); run("Close"); roiManager("Measure"); //Making square ROIs from Particles wait(500); add_squares=roiManager("count"); if (add_squares==0) { roiManager("Show All"); roiManager("Show All with labels"); waitForUser("Oops", "We didn't see any staining here. Try adjusting the Cell Detection Threshold settings in the next step... "); setTool("point"); makePoint(0, 0); selectWindow(full_name); } else { array=newArray(add_squares); for(i=0; iMake summed double-labeled images from z-stacks."); Dialog.addRadioButtonGroup("What type of file do you want to import?", items, 3, 1, "Semiautomated analysis of summed double-labeled Z-stack"); Dialog.show; choice = Dialog.getRadioButton; if (choice=="Semiautomated analysis of summed double-labeled Z-stack") { import_type = 5; run("__sub_PIPSQUEAK_Open_Double"); } else { if (choice=="Automatic analysis of summed double-labeled Z-stacks") { import_type = 6; run("__sub_PIPSQUEAK_Open_Double"); } if (choice=="->Make summed double-labeled images from z-stacks.") { //Dialog.create("Stacks folder"); //Dialog.addMessage("Before using this function, please place z-stack images into a folder titled 'Stacks' within your experiment folder."); //Dialog.addMessage("ie, /Desktop/experiment folder/Stacks/image1... image20"); //Dialog.show(); run("__sub_PIPSQUEAK_double_sum""); } } } ///////////////////////////// macro "__sub_PIPSQUEAK_double_sum" { // summing images. countDouble = 1 Ldest = getDirectory("Choose a Directory "); //load from name = getTitle; countDouble++ if (countDouble == 2) { Sdest = Ldest+"/summed/"; //save to Dialog.create("Save location"); Dialog.addMessage("Select a place to save the summed image. ie, /Users/John/Desktop"); Dialog.addString("Save to: ", Sdest); Dialog.show(); Sdest = Dialog.getString(Ldest="/summed/"); print("Save location: "+Sdest); } else { wait(100); } if (File.exists(Sdest+name+"/")) { wait(100); } else { File.makeDirectory(Sdest+name+"/"); } sfold = Sdest + name; stackfold = getFileList(Ldest); //if(!File.exists(sfold)) { // File.makeDirectory(sfold); //} for(i=0; i0){ selectImage(nImages); close(); } } ///////////////////////////// macro "__sub_PIPSQUEAK_Open_Double" { // opening previously summed images waitForUser("Select First Image", "Please open the first image of the subject series."); open(); Dialog.create("Subject ID"); Dialog.addMessage("Please enter the Subject ID name or number"); Dialog.addString("Subject ID:", "eg: 2B"); Dialog.show subject_id = Dialog.getString(); run("Set Measurements...", "area mean standard min center redirect=None decimal=3"); run("Set Scale...", "distance=scale_size known=scale_known pixel=scale_pixel unit=&scale_unit global"); first_image = getTitle; dir = getDirectory("image"); index = lastIndexOf(first_image, "."); if (index!=-1) first_image = substring(first_image, 0, index); print("\n"+first_image+" loaded."); series_name = substring(first_image, 0, index-2); first_open_double = series_name; subDir = dir+"/"+series_name+"/"; File.makeDirectory(subDir); //print("subDir = "+subDir); if(endsWith(first_image,first_suffix)) { open(series_name+"_"+second_suffix+".tif"); second_image = getTitle; if (index!=-1) second_image = substring(second_image, 0, index); print(second_image+" loaded."); run("__sub_PIPSQUEAK_Double_Background"); } else { waitForUser("Please update Settings to match numbering suffixes of double-label image series"); run("PIPSQUEAK"); } } ////////////////////////////// /* //MACRO REMOVED BECAUSE SUBJECT SEQUENCE LOADING COMPLICATED BY IMAGE ORDER. MUST REVISIT STRATEGY TO MAKE THIS FUNCTION WORK. macro "__sub_PIPSQUEAK_OpenNext_Double" { if (total_images == second_suffix) { // this macro automatically opened the next image run("Open Next"); } else { series_diff = total_images-second_suffix; for (i = 0; i < series_diff; i++) { run("Open Next"); }} first_image = getTitle; index = lastIndexOf(first_image, "."); series_name = substring(first_image, 0, index-2); last_open_double = series_name; //print(series_name); //if (last_open_double==first_open_double) { // print("\n"+"All images processed! Done."); // makeRectangle(0, 0, 0, 0); // run("Revert"); // run("Clear Results"); // run("Close"); // selectWindow(first_image+".tif"); // run("Close"); // } else { // wait(100); // } if (index!=-1) first_image = substring(first_image, 0, index); if(endsWith(first_image,first_suffix)) { print("\n"+first_image+" loaded."); open(series_name+"_"+second_suffix+".tif"); second_image = getTitle; if (index!=-1) second_image = substring(second_image, 0, index); if(endsWith(second_image,second_suffix)) { print(second_image+" loaded."); run("__sub_PIPSQUEAK_Double_Background"); } else { waitForUser("Please update Settings to match numbering suffixes of double-label image series"); run("__sub_PIPSQUEAK_Open_Double"); } } */ /////////////////////////////// macro "__sub_PIPSQUEAK_Double_Background" { //the meat of the pipsqueak. DL= double-label. SL= single-label. //First Image // Selecting Background first_image_tif = first_image+".tif"; //image names are consistently kept as "first_image_tif" and "second_image_tif" throughout the double-labeled macro(s) second_image_tif = second_image+".tif"; //even though the actual images are duplicated and named things like "first_image-2.tif" run("Clear Results"); //clearing the template run("ROI Manager..."); //opening ROI manager roiManager("reset"); // clearing ROI manager roiManager("Show All"); //turning on show all labels roiManager("Show All with labels"); selectWindow(first_image_tif); //grabbing first image height = getHeight; //getting dimensions in order to place background ROIs around images of any size width = getWidth; makeRectangle((6*(width-40)/6), (0.1*(height-40)/5), 30, 30); //placing 20 ROIs around the perimeter of the image roiManager("Add"); makeRectangle((6*(width-40)/6), (1*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((6*(width-40)/6), (2*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((6*(width-40)/6), (3*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((6*(width-40)/6), (4*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((6*(width-40)/6), (5*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((5*(width-40)/6), (5*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((4*(width-40)/6), (5*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((3*(width-40)/6), (5*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((2*(width-40)/6), (5*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((1*(width-40)/6), (5*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((0.1*(width-40)/6), (5*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((0.1*(width-40)/6), (4*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((0.1*(width-40)/6), (3*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((0.1*(width-40)/6), (2*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((0.1*(width-40)/6), (1*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((0.1*(width-40)/6), (0.1*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((1*(width-40)/6), (0.1*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((2*(width-40)/6), (0.1*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((3*(width-40)/6), (0.1*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((4*(width-40)/6), (0.1*(height-40)/5), 30, 30); roiManager("Add"); makeRectangle((5*(width-40)/6), (0.1*(height-40)/5), 30, 30); roiManager("Add"); run("Subtract Background...", "rolling=10"); //before measuring the image background for threshold, running rolling ball subtraction roiManager("Select", newArray(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,21)); //measuring all the ROIs in order to run stats and select the right ones roiManager("Measure"); // Calculating lower threshold background value in "Mean" column DL1_m=0; DL1_bkgd_mean=0; DL1_meanbkgd=0; DL1_std=0; DL1_bkgd_std=0; DL1_stdbkgd=0; DL1_m = nResults; //building an array for the ROI means. DL1_bkgd_mean = newArray(DL1_m); run("Select None"); for (i=0; i80%) with the square, roiManager("deselect"); roiManager("Select", a2-1); //move back one spot and select that square, roiManager("Delete"); // then delete it because we know that it was a non-overlapping square and should no longer be considered for colabeling. //print("Square "+a2+" deleted. AAAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHH"); //square ROI death scene. no_overlap=no_overlap+1; // add one to the number of square not overlapping so that we can lower the total squares. a=a-1; //remove one square from the counted number of squares. Semi repetitive with last variable, but each serve a function in the top IF loop. } if(b2==(double_label_first_type) && (no_co==1)){ // if we have checked all circles and there was an overlap detected //print("Total circles checked: "+bTotal); //then, print # circles checked. (next step is to exit loop because a!<(double_label_all_types-no_overlap)). //print("loop = "+n+1); //print("\n"); //wait(10); } if(b2==(double_label_first_type) && (no_co>1)){ // if checked all circles and there were multiple overlaps, selectWindow(second_image_tif); //select the WFA image run("Clear Results"); roiManager("deselect"); roiManager("Select", a); //select the square ROI roiManager("Measure"); //measure the square ROI so we can... CoM_x_square=getResult("XM", 0); // grab the squares's center of mass x-coordinate from the results. CoM_y_square=getResult("YM", 0); // grab the squares's center of mass y-coordinate from the results. CoM_tot_square = CoM_x_square+CoM_y_square; //making the total value (number only used for comparison to circles). run("Clear Results"); selectWindow(first_image_tif); //select the PV image roiManager("deselect"); roiManager("Select", co_roi_array); //select the overlapping ROIs roiManager("Measure"); for(i=0; i0){ print("Removed circle ROIs (these were multiple overlaps with square ROIs):"); Array.print(removed_circles_array); } print("Squares saved:"); Array.print(saved_squares_array); */ roiManager("reset"); ////////////////////////////////////////////// /* In this section we are identifying the CIRCLES that have overlapping SQUARES. */ roiManager("Open", subDir+second_image+second_stain_type+"_double-label_ROIoverlay.zip"); double_label_second_type_b = roiManager("count"); double_label_second_type_b_array = Array.getSequence(double_label_second_type_b); //waitForUser(""); roiManager("Open", subDir+first_image+first_stain_type+"_refined-single-label_ROIoverlay.zip"); double_label_all_types = roiManager("count"); double_label_all_types_array = Array.getSequence(double_label_all_types); double_label_first_type = double_label_all_types-double_label_second_type_b; double_label_first_type_start = double_label_second_type_b; //////// /* print("double_label_first_type = "+double_label_first_type); print("double_label_second_type_b = "+double_label_second_type_b); print("double_label_all_types = "+double_label_all_types); print("double_label_first_type_start = "+double_label_first_type_start); */ //////// //waitForUser(""); n=0; //count loops no_overlap=0; //number of circles without square overlap. co_roi_array2 = newArray(n); // this array will be concatenated with the "d" value for each overlapping square so the ROIs can be selected. co_roi_array2_UI = newArray(n); // this array will be concatenated with the "d2" value for each overlapping square so the user can see multiple overlaps. saved_circles_array = newArray(n); //building an array to remember which circle ROIs overlap (for ROI selection) for(c=double_label_first_type_start; c<(double_label_all_types-no_overlap); c++){ //circles roiManager("Select", c); c2=c+1; //c2 is a counting variable to correct for the ROI manager starting at ROI #0. //print("circle = "+c2); dTotal=0; // number of squares checked against circle "c2". no_co=0; // yes/no variable determining whether overlap was found. for(d=0; d80%) with the circle, roiManager("deselect"); roiManager("Select", c2-1); roiManager("Delete"); //print("circle "+c2+" deleted. AAAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHH"); no_overlap=no_overlap+1; // add one to the number of circles not overlapping so that we can lower the total circles. c=c-1;//remove one circle from the counted number of circle. Semi repetitive with last variable, but each serve a function in the top IF loop. } } n=n+1; //print("Total squares checked: "+dTotal); //print("loop = "+n); //print("\n"); } //waitForUser(""); roiManager("Select", double_label_second_type_b_array); roiManager("Delete"); //saving ROI overlay save_circleDL_ROIs=roiManager("count"); //print("number of saved circle ROIs = "+save_circleDL_ROIs); //print("\n"+first_image); //print("Circles ROIs saved:"); //Array.print(saved_circles_array); circle_DL_array=newArray(save_circleDL_ROIs); // saving the list of DL circle ROIs for(i=0; i0){ print("Removed circle ROIs (these were multiple overlaps with square ROIs):"); Array.print(removed_circles_array); } print("Circle DL ROIs = "+save_circleDL_ROIs); print("\n"+second_image); print("Square DL ROIs = "+save_squareDL_ROIs); //print("\n"+"Done"); roiManager("reset"); run("__sub_PIPSQUEAK_measure_Double_Background_DL1and2_ROIs"); } //\\//\\//\\//\\//\\//\\//\\ macro "__sub_PIPSQUEAK_measure_Double_Background_DL1and2_ROIs" { //this macro simply recalls the ROIs defined in the last macro in order to measure the values again. first_image_tif = first_image+"-2.tif"; second_image_tif = second_image+"-2.tif"; roiManager("Open", subDir+first_image+first_stain_type+"_double-label_ROIoverlay.zip"); roiManager("Open", subDir+second_image+second_stain_type+"_double-label_ROIoverlay.zip"); if (import_type==6) { //if run in automatic mode, no ROI check step offered. wait(300); } else { //otherwise, it opens the merge image and overlays the ROIs. open(series_name+"_"+merged_suffix+".tif"); merged_image = getTitle; roiManager("Show All"); roiManager("Show All with labels"); Dialog.create("How Does That Look?"); //the first step is asking the user if they want to edit either ROI set. items = newArray(first_stain_type, second_stain_type, "Accept double labeling as is."); Dialog.addRadioButtonGroup("Here is your chance to adjust the ROIs to better identify PNNs. Which double-labeled cells would you like to adjust?", items, 3, 1, "Accept double labeling as is."); Dialog.show; choice = Dialog.getRadioButton; if (choice==first_stain_type) { setTool("oval"); roiManager("reset"); roiManager("Open", subDir+first_image+first_stain_type+"_double-label_ROIoverlay.zip"); waitForUser("How Does That Look?", "Here is your chance to adjust the double-labeling. Try moving, adding, or deleting ROIs. **THEN** press OK."); roiManager("deselect"); roiManager("Save", subDir+first_image+first_stain_type+"_double-label_ROIoverlay.zip"); wait(100); Dialog.create("Adjust the other stain?"); //then the second step is to ask the user if they want to edit the other stain's ROIs. items = newArray("Yes", "No, accept double labeling as is."); Dialog.addRadioButtonGroup("Do you want to also adjust "+second_stain_type+" double-labeling?", items, 2, 1, "Yes"); Dialog.show; choice = Dialog.getRadioButton; if (choice=="Yes") { setTool("rectangle"); roiManager("reset"); roiManager("Open", subDir+second_image+second_stain_type+"_double-label_ROIoverlay.zip"); waitForUser("How Does That Look?", "Here is your chance to adjust the double-labeling. Try moving, adding, or deleting ROIs. **THEN** press OK."); roiManager("deselect"); roiManager("Save", subDir+second_image+second_stain_type+"_double-label_ROIoverlay.zip"); wait(100); roiManager("reset"); selectWindow(merged_image); run("Close"); run("__sub_PIPSQUEAK_measure_Double_Background_DL1and2_ROIs"); } if (choice=="No, accept double labeling as is.") { //well, aren't you confident. } } if (choice==second_stain_type) { setTool("rectangle"); roiManager("reset"); roiManager("Open", subDir+second_image+second_stain_type+"_double-label_ROIoverlay.zip"); waitForUser("How Does That Look?", "Here is your chance to adjust the double-labeling. Try moving, adding, or deleting ROIs. **THEN** press OK."); roiManager("deselect"); roiManager("Save", subDir+second_image+second_stain_type+"_double-label_ROIoverlay.zip"); wait(100); Dialog.create("Adjust the other stain?"); //again, second step, but after starting with the alternative stain. items = newArray("Yes", "No, accept double labeling as is."); Dialog.addRadioButtonGroup("Do you want to also adjust "+first_stain_type+" double-labeling?", items, 2, 1, "Yes"); Dialog.show; choice = Dialog.getRadioButton; if (choice=="Yes") { setTool("oval"); roiManager("reset"); roiManager("Open", subDir+first_image+first_stain_type+"_double-label_ROIoverlay.zip"); waitForUser("How Does That Look?", "Here is your chance to adjust the double-labeling. Try moving, adding, or deleting ROIs. **THEN** press OK."); roiManager("deselect"); roiManager("Save", subDir+first_image+first_stain_type+"_double-label_ROIoverlay.zip"); wait(100); roiManager("reset"); selectWindow(merged_image); run("Close"); run("__sub_PIPSQUEAK_measure_Double_Background_DL1and2_ROIs"); } if (choice=="No, accept double labeling as is.") { //well, aren't you confident. } } if (choice=="Accept double labeling as is.") { //well, aren't you confident. } } selectWindow(merged_image); run("Close"); roiManager("reset"); //\\\\\\\\\\\\\ //actually measuring the double labeled ROIs (image 1) run("Clear Results"); roiManager("Open", subDir+first_image+first_stain_type+"_double-label_ROIoverlay.zip"); DL_ROIs=0; DL_ROIs =roiManager("count"); array=newArray(DL_ROIs); for(i=0; i