//////////////////////////////////////////////////////////////// /* 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) 2017, 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 <<< */ //////////////////////////////////////////////////////////////// //Global variables var TimeString = "BlankDate"; var scale_size = 1.194; var scale_known = 1; var scale_pixel = 1; var scale_unit = "um"; var background_setting = "Low"; var set_intensity_low_threshold = 1.165; var set_intensity_high_threshold = 5000; var set_low_particlesize = 70; var set_high_particlesize = 500; 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 ROI_type_SL = "Square"; var countSingle = 0; 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.5; var DL1_set_intensity_high_threshold = 5000; var DL1_set_low_particlesize = 40; var DL1_set_high_particlesize = 500; 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 ROI_type_DL1 = "Circle"; 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 = 500; 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 ROI_type_DL2 = "Square"; var first_image_TL = 0; var second_image_TL var third_image_TL = 0; var merged_image_TL = 0; var series_name_TL = 0; var subDir_TL = 0; var first_suffix_TL= 2; var second_suffix_TL = 3; var third_suffix_TL = 4; var merged_suffix_TL = 1; var total_images_TL = 4; var first_stain_type_TL = "PV"; var TL1_set_intensity_low_threshold = 1.5; var TL1_set_intensity_high_threshold = 5000; var TL1_set_low_particlesize = 40; var TL1_set_high_particlesize = 500; var TL1_set_low_circularity = 0.02; var TL1_set_high_circularity = 1.00; var TL1_set_roi_enlargement = -1.00; var TL1_lower = 0; var ROI_type_TL1 = "Circle"; var second_stain_type_TL = "WFA"; var TL2_set_intensity_low_threshold = 1.165; var TL2_set_intensity_high_threshold = 5000; var TL2_set_low_particlesize = 70; var TL2_set_high_particlesize = 500; var TL2_set_low_circularity = 0.02; var TL2_set_high_circularity = 1.00; var TL2_set_roi_enlargement = 1.00; var TL2_lower = 0; var ROI_type_TL2 = "Square"; var third_stain_type_TL = "8-oxo"; var TL3_set_intensity_low_threshold = 0.5; var TL3_set_intensity_high_threshold = 5000; var TL3_set_low_particlesize = 7; var TL3_set_high_particlesize = 250; var TL3_set_low_circularity = 0.02; var TL3_set_high_circularity = 1.00; var TL3_set_roi_enlargement = 1.00; var TL3_lower = 0; var ROI_type_TL3 = "Circle"; 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; var first_SL_run=1; /////////////////////////// macro "PIPSQUEAK" { getDateAndTime(year, month, dayOfWeek, dayOfMonth, hour, minute, second, msec); TimeString ="_"+month+1+" "+dayOfMonth+" "+year+" at "+hour+" "+minute; if (pipsqueakCount==1){ ///call home tracking URL //UPDATE HERE (1/4 and 2/4)-> call_home_url = "http://www.google-analytics.com/__utm.gif?utmwv=5.1.7&utms=1&utmn=1894752493&utmhn=www.jabstracts.org/&utmcs=UTF-8&utmsr=1280×1024&utmsc=24-bit&utmul=en-us&utmje=1&utmfl=10.3%20r183&utmdt=Tracking%20QR%20Codes%20with%20Google%20Analytics&utmhid=1681965357&utmr=http%3A%2F%2Fwww.imagejnih.gov%2F&utmp=%2Fjabstracts.org%2Fpipsqueak%2Fcall_home%2Fv3-00b%2F&utmac=UA-83183702-1&utmcc=__utma%3D230887938.1463229748.1317737798.1317737798.1317737798.1%3B%2B__utmz%3D230887938.1317737798.1.1.utmcsr%3Dgoogle%7Cutmccn%3D(organic)%7Cutmcmd%3Dorganic%7Cutmctr%3DPIPSQUEAK%2Fv3.00b%3B&utmu=DC~"; File.openUrlAsString(call_home_url); wait(50); print("\\Clear"); /// //UPDATE HERE (3/4)-> print("PIPSQUEAK! v3.00b Perineuronal net Intensity Program for the Standardization and Quantification of ECM Analysis."); print("\n"+"Copyright (C) 2017, John H. Harkness, PhD."); print("Protocol by Megan Slaker, PhD."); print("Lab of Barb Sorg, PhD., Washington State University, Vancouver"); print("\n"+"FOR ACCURATE RESULTS, IT IS CRITICAL THAT YOUR IMAGE DIMENSIONS ARE CORRECTLY ENTERED (i.e. pixels per known distance)."); //UPDATE HERE (4/4)-> waitForUser("PIPSQUEAK version 3.00b, August 3rd, 2017 \n \n 2.12 CHANGE LOG: This is a big one. New background selection method to improve detection of faint staining, \n but it's your choice! See settings. Also, choose your fav ROI shape! See settings. \n UI improvements. Also, check out the instructional videos at labs.wsu.edu/sorg/research-resources. \n Squashed a pesky little bug that sometimes led to incorrect measurements during double-label analysis (Thanks Hayley!) \n \n 3.00 CHANGE LOG: This is a pretty big one. Fixed naming error. Added the ability to import previous ROI list. \n Fixed Double-label ROI mismatch error. Removed the Count Cell function because the Single-label function does it better. \n Finally, user settings are (finally) saved between uses!! \n Oh yeah, and added triple-label analysis. \n \n 3.00b CHANGE LOG: Just some bugs."); wait(1000); pipsqueakCount = pipsqueakCount+1; } else { wait(50); } print("Background Setting: "+background_setting); print("Distance in pixels: "+scale_size+"\n"+"Known distance: "+scale_known+"\n"+"Pixel aspect ratio: "+scale_pixel+"\n"+"Unit of length: "+scale_unit); print("Date on saved files will be '"+TimeString+"'"); print("\n"); Dialog.create("Welcome"); items0 = newArray("Single label analysis", "->Settings", "Double label analysis", "->Contact Us and/or Report a bug", "Triple label analysis"); Dialog.addRadioButtonGroup("What would you like to do?", items0, 3, 2, " "); Dialog.show; choice0 = Dialog.getRadioButton; if (choice0 =="Single label analysis") { run("_ps_single"); } if (choice0 =="Double label analysis") { run("_ps_double"); } if (choice0=="Triple label analysis") { run("_ps_triple"); } if (choice0 =="->Contact Us and/or Report a bug") { //Dialog.addHelp("http://www.labs.wsu.edu/sorg/research-resources/") waitForUser("Thanks! Please log bugs as best you can (screen shot, description, etc) and send to john.harkness@wsu.edu . \n For questions or help, please use the same email address. Thanks for using PIPSQUEAK!"); run("PIPSQUEAK"); } //if (choice0 =="->Help") { // waitForUser("Please visit https://labs.wsu.edu/sorg/research-resources"); // run("PIPSQUEAK"); //} if (choice0 =="->Settings") { Dialog.create("Settings Menu"); items1 = newArray("Image dimensions and scale settings", "Background calculation settings", "Single label analysis settings", "Double label analysis settings", "Triple label analysis settings"); Dialog.addRadioButtonGroup("What would you like to do?", items1, 5, 1, " "); Dialog.show; choice1 = Dialog.getRadioButton; if (choice1 =="Image dimensions and scale settings") { Dialog.create("Image dimensions and scale settings"); 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.show; scale_size = Dialog.getNumber(); scale_known = Dialog.getNumber();; scale_pixel = Dialog.getNumber();;; scale_unit = Dialog.getString(); run("PIPSQUEAK"); } if (choice1 =="Background calculation settings") { Dialog.create("Background calculation settings"); Dialog.addMessage("Adjustments will alter cell determination and MAY reduce identification specificity."); Dialog.addMessage("Proceed with caution: here be dragons."); Dialog.addMessage(" "); Dialog.addMessage("High background subtraction: This is the original setting for v2.02 and below. It removes more background, but may miss lightly stained cells."); Dialog.addMessage("Low background subtraction: This is the improved background setting. It is more sensitive for lightly stained cells."); items2 = newArray("High", "Low"); Dialog.addRadioButtonGroup("Which background subtraction setting would you like to use?", items2, 2, 1, background_setting); Dialog.show; choice2 = Dialog.getRadioButton; if (choice2 =="High") { background_setting = "High"; run("PIPSQUEAK"); } if (choice2 =="Low") { background_setting = "Low"; run("PIPSQUEAK"); } } if (choice1 =="Single label analysis settings") { Dialog.create("Single-label Intensity Analysis Settings"); Dialog.addMessage("Adjustments will alter cell determination and MAY reduce identification specificity."); Dialog.addMessage("Proceed with caution: here be dragons."); 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); items3 = newArray("As-detected", "Square", "Circle"); Dialog.addRadioButtonGroup("Shape of ROIs:", items3, 3, 1, ROI_type_SL); Dialog.show; 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();;;;;;; choice3 = Dialog.getRadioButton; if (choice3 =="As-detected") { ROI_type_SL = "As-detected"; } if (choice3 =="Square") { ROI_type_SL = "Square"; } if (choice3 =="Circle") { ROI_type_SL = "Circle"; } run("PIPSQUEAK"); } if (choice1 =="Double label analysis settings") { Dialog.create("Double-label Intensity Analysis Settings"); Dialog.addMessage("**Window 1 of 2**"); 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.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); items4 = newArray("As-detected", "Square", "Circle"); Dialog.addRadioButtonGroup("Shape of ROIs:", items4, 3, 1, ROI_type_DL1); 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();;;;;;;; choice4 = Dialog.getRadioButton; if (choice4 =="As-detected") { ROI_type_DL1 = "As-detected"; } if (choice4 == "Square") { ROI_type_DL1 = "Square"; } if (choice4 == "Circle") { ROI_type_DL1 = "Circle"; } //next window Dialog.create("Double-label Intensity Analysis Settings"); Dialog.addMessage("**Window 2 of 2**"); 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); items5 = newArray("As-detected", "Square", "Circle"); Dialog.addRadioButtonGroup("Shape of ROIs:", items5, 3, 1, ROI_type_DL2); Dialog.show; 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();;;;;;;; choice5 = Dialog.getRadioButton; if (choice5 == "As-detected") { ROI_type_DL2 = "As-detected"; } if (choice5 == "Square") { ROI_type_DL2 = "Square"; } if (choice5 == "Circle") { ROI_type_DL2 = "Circle"; } run("PIPSQUEAK"); } if (choice1 == "Triple label analysis settings") { Dialog.create(" Triple-label Intensity Analysis Settings"); Dialog.addMessage("**Window 1 of 3**"); 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_TL); Dialog.addNumber("Second image (if possible, larger volume stain):", second_suffix_TL); Dialog.addNumber("Third image (if possible, smaller volume stain):", third_suffix_TL); Dialog.addNumber("Merged image:", merged_suffix_TL); //Dialog.addNumber("Total number of stains plus composite in each subject series:", total_images); //REMOVED FOR NOW—SEE NOTE IN "_ps_OPENNEXT_DOUBLE". Dialog.addMessage(" "); Dialog.addMessage("*First stain parameters*"); Dialog.addString("Stain type:", first_stain_type_TL); Dialog.addNumber("Lower threshold multiplier:", TL1_set_intensity_low_threshold); Dialog.addNumber("Upper threshold limit:", TL1_set_intensity_high_threshold); Dialog.addNumber("Lower limit particle size:", TL1_set_low_particlesize); Dialog.addNumber("Upper limit particle size:", TL1_set_high_particlesize); Dialog.addNumber("Lower limit circularity:", TL1_set_low_circularity); Dialog.addNumber("Upper limit circularity:", TL1_set_high_circularity); Dialog.addNumber("ROI Enlargement (pixels):", TL1_set_roi_enlargement); items6 = newArray("As-detected", "Square", "Circle"); Dialog.addRadioButtonGroup("Shape of ROIs:", items6, 3, 1, ROI_type_TL1); Dialog.show first_suffix_TL = Dialog.getNumber(); second_suffix_TL = Dialog.getNumber();; third_suffix_TL = Dialog.getNumber();;; merged_suffix_TL = Dialog.getNumber();;;; //total_images = Dialog.getNumber();;;;; first_stain_type_TL = Dialog.getString(); TL1_set_intensity_low_threshold = Dialog.getNumber();; TL1_set_intensity_high_threshold = Dialog.getNumber();;; TL1_set_low_particlesize = Dialog.getNumber();;;; TL1_set_high_particlesize = Dialog.getNumber();;;;; TL1_set_low_circularity = Dialog.getNumber();;;;;; TL1_set_high_circularity = Dialog.getNumber();;;;;;; TL1_set_roi_enlargement = Dialog.getNumber();;;;;;;; choice6 = Dialog.getRadioButton; if (choice6 =="As-detected") { ROI_type_TL1 = "As-detected"; } if (choice6 == "Square") { ROI_type_TL1 = "Square"; } if (choice6 == "Circle") { ROI_type_TL1 = "Circle"; } Dialog.create(" Triple-label Intensity Analysis Settings"); Dialog.addMessage("**Window 2 of 3**"); Dialog.addMessage(" "); Dialog.addMessage("*Second stain parameters*"); Dialog.addString("Stain type:", second_stain_type_TL); Dialog.addNumber("Lower threshold multiplier:", TL2_set_intensity_low_threshold); Dialog.addNumber("Upper threshold limit:", TL2_set_intensity_high_threshold); Dialog.addNumber("Lower limit particle size:", TL2_set_low_particlesize); Dialog.addNumber("Upper limit particle size:", TL2_set_high_particlesize); Dialog.addNumber("Lower limit circularity:", TL2_set_low_circularity); Dialog.addNumber("Upper limit circularity:", TL2_set_high_circularity); Dialog.addNumber("ROI Enlargement (pixels):", TL2_set_roi_enlargement); items7 = newArray("As-detected", "Square", "Circle"); Dialog.addRadioButtonGroup("Shape of ROIs:", items7, 3, 1, ROI_type_TL2); Dialog.show; second_stain_type_TL = Dialog.getString(); TL2_set_intensity_low_threshold = Dialog.getNumber();; TL2_set_intensity_high_threshold = Dialog.getNumber();;; TL2_set_low_particlesize = Dialog.getNumber();;;; TL2_set_high_particlesize = Dialog.getNumber();;;;; TL2_set_low_circularity = Dialog.getNumber();;;;;; TL2_set_high_circularity = Dialog.getNumber();;;;;;; TL2_set_roi_enlargement = Dialog.getNumber();;;;;;;; choice7 = Dialog.getRadioButton; if (choice7 =="As-detected") { ROI_type_TL2 = "As-detected"; } if (choice7 == "Square") { ROI_type_TL2 = "Square"; } if (choice7 == "Circle") { ROI_type_TL2 = "Circle"; } Dialog.create(" Triple-label Intensity Analysis Settings"); Dialog.addMessage("**Window 3 of 3**");; Dialog.addMessage(" "); Dialog.addMessage("*Third stain parameters*"); Dialog.addString("Stain type:", third_stain_type_TL); Dialog.addNumber("Lower threshold multiplier:", TL3_set_intensity_low_threshold); Dialog.addNumber("Upper threshold limit:", TL3_set_intensity_high_threshold); Dialog.addNumber("Lower limit particle size:", TL3_set_low_particlesize); Dialog.addNumber("Upper limit particle size:", TL3_set_high_particlesize); Dialog.addNumber("Lower limit circularity:", TL3_set_low_circularity); Dialog.addNumber("Upper limit circularity:", TL3_set_high_circularity); Dialog.addNumber("ROI Enlargement (pixels):", TL3_set_roi_enlargement); items8 = newArray("As-detected", "Square", "Circle"); Dialog.addRadioButtonGroup("Shape of ROIs:", items8, 3, 1, ROI_type_TL3); Dialog.show; third_stain_type_TL = Dialog.getString(); TL3_set_intensity_low_threshold = Dialog.getNumber();; TL3_set_intensity_high_threshold = Dialog.getNumber();;; TL3_set_low_particlesize = Dialog.getNumber();;;; TL3_set_high_particlesize = Dialog.getNumber();;;;; TL3_set_low_circularity = Dialog.getNumber();;;;;; TL3_set_high_circularity = Dialog.getNumber();;;;;;; TL3_set_roi_enlargement = Dialog.getNumber();;;;;;;; choice8 = Dialog.getRadioButton; if (choice8 =="As-detected") { ROI_type_TL3 = "As-detected"; } if (choice8 == "Square") { ROI_type_TL3 = "Square"; } if (choice8 == "Circle") { ROI_type_TL3 = "Circle"; run("PIPSQUEAK"); } } } } ////////////////////////// macro "_ps_single" { Dialog.create("Import Type"); //items = newArray("Semiautomated analysis of raw, non-summed, individual Z-stacks", "Semiautomated analysis of summed single-labeled images", "Automatic analysis of summed single-labeled images", "->Make summed single-labeled images from Z-stacks."); items = newArray("Semiautomated analysis of summed single-labeled images", "Automatic analysis of summed single-labeled images", "->Make summed single-labeled images from Z-stacks."); Dialog.addRadioButtonGroup("What type of file do you want to import?", items, 3, 1, "Semiautomated analysis of summed single-labeled images"); Dialog.show; choice = Dialog.getRadioButton; /* if (choice=="Semiautomated analysis of raw, non-summed, individual Tiffs") { import_type=1; run("_ps_Import"); } */ if (choice=="Semiautomated analysis of summed single-labeled images") { import_type=2; run("_ps_Import_Summed"); } if (choice=="Automatic analysis of summed single-labeled images") { import_type=3; run("_ps_Auto_Import_Summed"); } if (choice=="->Make summed single-labeled images from Z-stacks.") { Dialog.create("Stacks folder"); Dialog.addMessage("Before using this function, please place folders containing Z-stack images within an experiment folder. Then choose the experiment folder."); Dialog.addMessage("ie, /Desktop/EXPERIMENT FOLDER/Subject folder/image1... image20"); Dialog.show(); run("_ps_z-project"); } //////////////////////////// macro "_ps_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("_ps_Background"); } ///////////////////////////// macro "_ps_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("_ps_Background"); } //////////////////////////////// macro "_ps_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("_ps_Background"); } //////////////////////////////// macro "_ps_z-project" { //makes summed image from z-stack Ldest = getDirectory("Choose a Directory "); //load from Sdest = Ldest+"/summed/"; //save at sfold = Sdest stackfold = getFileList(Ldest); if(!File.exists(sfold)) { File.makeDirectory(sfold); } for(i=0; i0){ selectImage(nImages); close(); } } } } } run("_ps_single"); } //////////////////////////////// macro "_ps_OpenNext_Single" { //import_type=3; makeRectangle(0, 0, 0, 0); run("Revert"); run("Open Next"); 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); last_open = name; if (last_open==first_open) { print("\n"+"All images processed! Done."); makeRectangle(0, 0, 0, 0); run("Revert"); run("Clear Results"); //run("Close"); selectWindow(name+".tif"); run("Close"); } else { print ("\n"+last_open+" loaded."); run ("_ps_Background"); } } /////////////////////////////// macro "_ps_Background" { // Selecting Background run("Clear Results"); run("ROI Manager..."); roiManager("reset"); roiManager("Show All"); roiManager("Show All with labels"); 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(); height = getHeight; width = getWidth; selectWindow(full_name); run("Duplicate...", " "); selectWindow(full_name); makeRectangle((6*(width-40)/6), (0.1*(height-40)/5), 30, 30); 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"); 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)); roiManager("Measure"); // Calculating lower threshold background value in "Mean" column m=0; bkgd_mean=0; meanbkgd=0; std=0; bkgd_std=0; stdbkgd=0; m = nResults; bkgd_mean = newArray(m); run("Select None"); 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 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 images"); Dialog.show; choice = Dialog.getRadioButton; if (choice=="Semiautomated analysis of summed double-labeled images") { import_type = 5; run("_ps_Open_Double"); } else { if (choice=="Automatic analysis of summed double-labeled images") { import_type = 6; run("_ps_Open_Double"); } if (choice=="->Make summed double-labeled images from Z-stacks.") { Dialog.create("Stacks folder"); Dialog.addMessage("Before using this function, please place folders containing Z-stack images within an experiment folder. Then choose the experiment folder."); Dialog.addMessage("ie, /Desktop/EXPERIMENT FOLDER/Subject folder/image1... image20"); Dialog.show(); run("_ps_double_sum"); } } } ///////////////////////////// macro "_ps_double_sum" { // summing images. Ldest = getDirectory("Choose a Directory "); //load from Sdest = Ldest+"/summed/"; //save at sfold = Sdest stackfold = getFileList(Ldest); if(!File.exists(sfold)) { File.makeDirectory(sfold); } for(i=0; i0){ selectImage(nImages); close(); } } } } } run("_ps_double"); } ///////////////////////////// macro "_ps_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); 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("_ps_Double_Background"); } else { waitForUser("Please update Settings to match numbering suffixes of double-label image series"); run("PIPSQUEAK"); } } ////////////////////////////// macro "_ps_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" name = series_name+" "+first_stain_type+".txt"; //saving the results table in a sub folder. 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; i0) { //if yes ROIs, change the size of the ROIs based on global enlargement variable. array=newArray(DL1_add_circles); for(i=0; i0) { array=newArray(DL2_add_squares); for(i=0; ic_area){ // if the overlapping area is less 80% of the circle, no_co = no_co-1; //then, forget that an overlap was identified and move on (restart the loop). //waitForUser("circle "+b2+" identified but <80% overlap"); } else { co_roi_array = Array.concat(co_roi_array, b); //building an array to remember which circle ROIs overlap (for ROI selection) co_roi_array_UI = Array.concat(co_roi_array_UI, b2); //building an array to remember which circle ROIs overlap (for the human to understand) saved_squares_array = Array.concat(saved_squares_array, a); //print("co roi's:"); //Array.print(co_roi_array_UI); //waitForUser("circle "+b2+" identified and >80% overlap"); } } if(b2==(double_label_first_type-multi_b_removed) && (no_co==0)){ //if we have checked every circle and still not found a circle that overlap (>80%) 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. 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. //waitForUser("Square "+a2+" is a loner"); } if(b2==(double_label_first_type-multi_b_removed) && (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"); //waitForUser("Square "+a2+" has a friend"); //wait(10); } if(b2==(double_label_first_type-multi_b_removed) && (no_co>1)){ // if checked all circles and there were multiple overlaps, //i think there needs to be a check here to see if any of the circles have been previously identified. Something like: // //for(i=0; i if the previous square is the better overlap //then no_co-1, and the no_co>1 is resolved //else it resolves below with better CoM analysis. //if the other circle wins, //then saved_circles_array[i] should be retained in co-labeling with the previous square. //else it is deleted //else no problem, check next //} 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; ico_area){ // if the overlapping area is less 80% of the square, no_co = no_co-1; //then, forget that an overlap was identified and move on (restart the loop). //waitForUser("circle "+c2+" identified but <80% overlap"); } else { co_roi_array2 = Array.concat(co_roi_array2, d); //building an array to remember which circle ROIs overlap (for ROI selection) co_roi_array2_UI = Array.concat(co_roi_array2_UI, d2); //building an array to remember which circle ROIs overlap (for the human to understand) saved_circles_array = Array.concat(saved_circles_array, c); //building an array to remember which circle ROIs overlap (for ROI selection) //waitForUser("circle "+c2+" identified and >80% overlap"); } } if((d2==double_label_second_type_b) && (no_co==0)){ //if we have checked every square and still not found a square that overlap (>80%) with the circle, roiManager("deselect"); roiManager("Select", c2-1); roiManager("Delete"); 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. //waitForUser("circle "+c2+" is a loner"); } } n=n+1; } roiManager("Select", double_label_second_type_b_array); roiManager("Delete"); //saving ROI overlay save_circleDL_ROIs=roiManager("count"); 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); roiManager("reset"); run("_ps_measure_Double_Background_DL1and2_ROIs"); } //\\//\\//\\//\\//\\//\\//\\ macro "_ps_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"); selectWindow(merged_image); 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("_ps_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("_ps_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. } } if (import_type==5){ selectWindow(merged_image); run("Close"); } roiManager("reset"); //\\\\\\\\\\\\\ //actually measuring the double labeled ROIs (image 1) run("Clear Results"); selectWindow(first_image_tif); roiManager("Open", subDir+first_image+first_stain_type+"_double-label_ROIoverlay.zip"); name = series_name+" "+first_stain_type+" double-label.txt"; DL_ROIs=0; DL_ROIs =roiManager("count"); array=newArray(DL_ROIs); for(i=0; iMake summed triple-labeled images from Z-stacks."); Dialog.addRadioButtonGroup("What type of file do you want to import?", items, 3, 1, "Semiautomated analysis of summed triple-labeled Z-stack"); Dialog.show; choice = Dialog.getRadioButton; if (choice=="Semiautomated analysis of summed triple-labeled images") { import_type = 5; run("_ps_Open_Triple"); } else { if (choice=="Automatic analysis of summed triple-labeled images") { import_type = 6; run("_ps_Open_Triple"); } if (choice=="->Make summed triple-labeled images from Z-stacks.") { Dialog.create("Stacks folder"); Dialog.addMessage("Before using this function, please place folders containing Z-stack images within an experiment folder. Then choose the experiment folder."); Dialog.addMessage("ie, /Desktop/EXPERIMENT FOLDER/Subject folder/image1... image20"); Dialog.show(); run("_ps_triple_sum"); } } } ///////////////////////////// macro "_ps_triple_sum" { // summing images. Ldest = getDirectory("Choose a Directory "); //load from Sdest = Ldest+"/Summed/"; //save at sfold = Sdest stackfold = getFileList(Ldest); if(!File.exists(sfold)) { File.makeDirectory(sfold); } for(i=0; i0){ selectImage(nImages); close(); } } } } } run("_ps_triple"); } ///////////////////////////// macro "_ps_Open_Triple" { // opening previously summed images waitForUser("Select first Image", "Please open the "+first_stain_type_TL+" 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_TL = getTitle; dir = getDirectory("image"); index = lastIndexOf(first_image_TL, "."); if (index!=-1) first_image_TL = substring(first_image_TL, 0, index); print("\n"+first_image_TL+" loaded."); series_name_TL = substring(first_image_TL, 0, index-2); first_open_triple = series_name_TL; subDir_TL = dir+"/"+series_name_TL+"/"; File.makeDirectory(subDir_TL); //print("subDir_TL = "+subDir_TL_TL); if(endsWith(first_image_TL,first_suffix_TL)) { open(series_name_TL+"_"+second_suffix_TL+".tif"); second_image_TL = getTitle; if (index!=-1) second_image_TL = substring(second_image_TL, 0, index); print(second_image_TL+" loaded."); } else { waitForUser("Please update Settings to match numbering suffixes of triple-label image series"); run("PIPSQUEAK"); } if(endsWith(second_image_TL,second_suffix_TL)) { open(series_name_TL+"_"+third_suffix_TL+".tif"); third_image_TL = getTitle; if (index!=-1) third_image_TL = substring(third_image_TL, 0, index); print(third_image_TL+" loaded."); } else { waitForUser("Please update Settings to match numbering suffixes of triple-label image series"); run("PIPSQUEAK"); } if(endsWith(third_image_TL,third_suffix_TL)) { open(series_name_TL+"_"+merged_suffix_TL+".tif"); merged_image_TL = getTitle; if (index!=-1) merged_image_TL = substring(merged_image_TL, 0, index); print(merged_image_TL+" loaded."); run("_ps_Triple_Background"); } else { waitForUser("Please update Settings to match numbering suffixes of triple-label image series"); run("PIPSQUEAK"); } } } } } /////////////////////////////// macro "_ps_Triple_Background" { //the meat of the pipsqueak. TL= triple-label. DL= double-label. SL= single-label. //First Image // Selecting Background first_image_tif = first_image_TL+".tif"; //image names are consistently kept as "first_image_tif" and "second_image_tif" throughout the triple-labeled macro(s) second_image_tif = second_image_TL+".tif"; //even though the actual images are duplicated and named things like "first_image_TL-2.tif" third_image_tif = third_image_TL+".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; i0) { //if yes ROIs, change the size of the ROIs based on global enlargement variable. array=newArray(DL1_add_circles); for(i=0; i0) { array=newArray(DL2_add_squares); for(i=0; i0) { array=newArray(DL3_add_circles); for(i=0; ic_area){ // if the overlapping area is less 80% of the circle, no_co = no_co-1; //then, forget that an overlap was identified and move on (restart the loop). wait(5); //print("Nevermind, It failed 80% overlap. YYYYEEEEEAAAAH"); } else { co_roi_array = Array.concat(co_roi_array, b); //building an array to remember which circle ROIs overlap (for ROI selection) co_roi_array_UI = Array.concat(co_roi_array_UI, b2); //building an array to remember which circle ROIs overlap (for the human to understand) saved_squares_array_a = Array.concat(saved_squares_array_a, a); //print("Squares saved so far:"); //Array.print(saved_squares_array_a); } } if(b2==(double_label_first_type-multi_b_removed) && (no_co==0)){ //if we have checked every circle and still not found a circle that overlap (>80%) 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-multi_b_removed) && (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-multi_b_removed) && (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). wait(10); 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; ico_area){ // if the overlapping area is less 80% of the square, no_co = no_co-1; //then, forget that an overlap was identified and move on (restart the loop). //print("Nevermind, It failed 80% overlap. YYYYEEEEEAAAAH"); } else { co_roi_array2 = Array.concat(co_roi_array2, d); //building an array to remember which circle ROIs overlap (for ROI selection) co_roi_array2_UI = Array.concat(co_roi_array2_UI, d2); //building an array to remember which circle ROIs overlap (for the human to understand) saved_circles_array = Array.concat(saved_circles_array, c); //building an array to remember which circle ROIs overlap (for ROI selection) } } if((d2==double_label_second_type_b) && (no_co==0)){ //if we have checked every square and still not found a square that overlap (>80%) with the circle, roiManager("deselect"); roiManager("Select", c2-1); roiManager("Delete"); 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; } roiManager("Select", double_label_second_type_b_array); roiManager("Delete"); //saving ROI overlay save_circleDL_ROIs=roiManager("count"); 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_a); } print("Circle DL ROIs = "+save_circleDL_ROIs); print("\n"+second_image_TL); print("Square DL ROIs = "+save_squareDL_ROIs); roiManager("reset"); run("_ps_Triple_Background_DL3and2_ROIs"); } //\\//\\//\\//\\//\\//\\//\\ macro "_ps_Triple_Background_DL3and2_ROIs" { //this is the macro that identifies double-labeled cells between stains 3 and 2. //Double labeled cell identification third_image_tif = third_image_TL+"-2.tif"; second_image_tif = second_image_TL+"-2.tif"; //////////////////////////////////////////NEW DOUBLE ROI STUFF HERE DOWN/////////////////////////////////////////////////// roiManager("deselect"); roiManager("reset"); wait(50); selectWindow(second_image_tif); //select the WFA image roiManager("Open", subDir_TL+third_image_TL+third_stain_type_TL+"_single-label_ROIoverlay.zip"); double_label_third_type = roiManager("count"); // determines the number of circle ROIs double_label_third_type_array = Array.getSequence(double_label_third_type); roiManager("Open", subDir_TL+second_image_TL+second_stain_type_TL+"_single-label_ROIoverlay.zip"); roiManager("Show All"); roiManager("Show All with labels"); double_label_all_types = roiManager("count"); double_label_all_types_array = Array.getSequence(double_label_all_types); double_label_second_type = double_label_all_types-double_label_third_type; // determines the number of square ROIs double_label_second_type_start = double_label_third_type; // the ROI manager position of the first Square /* In this section we are identifying the squares that have overlapping cicrles. */ //waitForUser("Everything is loaded, let's start."); n=0; // number of time the square loop was run. no_overlap=0; //number of squares without circle overlap. multi_b_removed=0; //number of circles removed because resolved multiple overlap; removed_circles_array_c = newArray(n); saved_squares_array_c = newArray(n); for(a=double_label_second_type_start; a<(double_label_all_types-no_overlap-multi_b_removed); a++){ // squares. roiManager("Select", a); a2=a+1; //a2 is a counting variable to correct for the ROI manager starting at ROI #0. //print("square = "+a2); bTotal=0; // number of circles checked against square "a2". no_co=0; // yes/no variable determining whether overlap was found. co_roi_array = newArray(no_co); // this array will be concatenated with the "b" value for each overlapping circle so the ROIs can be selected. co_roi_array_UI = newArray(no_co); // this array will be concatenated with the "b2" value for each overlapping circle so the user can see multiple overlaps. CoM_distance_array = newArray(no_co); // making an array of the distances between the square CoM and the circle's CoM. for(b=0; b<(double_label_third_type-multi_b_removed); b++){ //circles. b2=b+1; //b2 is a counting variable to correct for the ROI manager starting at ROI #0. roiManager("Select", newArray(a, b)); //select the square the the circle roiManager("AND"); //build an overlapping ROI roiType = selectionType(); bTotal=bTotal+1; if(roiType==-1){ // and there is not overlapping area under the square and circle ROIs //print("No overlap: circle "+b2); //then, move on to the next (ie, restart the loop). } if(roiType!=-1){ // if there is overlap from the square and the circle, c = roiManager("Add"); //add the overlap to the ROI manager so that we can measure its size. no_co = no_co+1; // to remember that, yes, there is overlap. roiManager("deselect"); run("Clear Results"); //selectWindow(third_image_tif); //select the 8-oxo image roiManager("Select", b); //measure the size of the circle roiManager("Measure"); //selectWindow(second_image_tif); //select the pv image co_roi = (roiManager("count")-1); //find the overlap ROI (it's going to be the last one on the ROI manager list). roiManager("Select", co_roi); // select it. roiManager("Measure"); //measure the area. b2_area=getResult("Area", 0); // grab the circle-ROI's area from the results c_area=getResult("Area", 1); // grab the overlap-ROI's area from the results b2_area_80 = b2_area*0.8; // calculate 80% of the circle area (we're using 80% as an arbitrary threshold of minimum circle that should be within the square). wait(5); //print("b2 = "+b2_area); //print("c_area= "+c_area); //print("b2_80 = "+b2_area_80); //waitForUser("check area comparisons in log"); roiManager("Select", co_roi); roiManager("Delete"); //now removing it because we only wanted that new ROI to measure the area of overlap. if(b2_area_80>c_area){ // if the overlapping area is less 80% of the circle, no_co = no_co-1; //then, forget that an overlap was identified and move on (restart the loop). wait(5); } else { co_roi_array = Array.concat(co_roi_array, b); //building an array to remember which circle ROIs overlap (for ROI selection) co_roi_array_UI = Array.concat(co_roi_array_UI, b2); //building an array to remember which circle ROIs overlap (for the human to understand) saved_squares_array_c = Array.concat(saved_squares_array_c, a); } } if(b2==(double_label_third_type-multi_b_removed) && (no_co==0)) { //if we have checked every circle and still not found a circle that overlap (>80%) 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. 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. wait(5); } if(b2==(double_label_third_type-multi_b_removed) && (no_co==1)) { // if we have checked all circles and there was an overlap detected wait(5); } if(b2==(double_label_third_type-multi_b_removed) && (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). wait(10); run("Clear Results"); selectWindow(third_image_tif); //select the 8-oxo image roiManager("deselect"); roiManager("Select", co_roi_array); //select the overlapping ROIs roiManager("Measure"); wait(10); for(i=0; ico_area){ // if the overlapping area is less 80% of the square, no_co = (no_co-1); //then, forget that an overlap was identified and move on (restart the loop). //print("Nevermind, It failed 80% overlap. YYYYEEEEEAAAAH"); } else { co_roi_array2 = Array.concat(co_roi_array2, d); //building an array to remember which square ROIs overlap (for ROI selection) wait(5); co_roi_array2_UI = Array.concat(co_roi_array2_UI, d2); //building an array to remember which square ROIs overlap (for the human to understand) wait(5); saved_circles_array = Array.concat(saved_circles_array, c); //building an array to remember which circle ROIs overlap (for ROI selection) //print("Circles saved so far:"); //Array.print(saved_circles_array); wait(5); } } if((d2==double_label_second_type_b) && (no_co==0)){ //if we have checked every square and still not found a square that overlap (>80%) with the circle, roiManager("deselect"); wait(10); 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. //wait(5); } } n=n+1; } //waitForUser(""); roiManager("deselect"); roiManager("Select", double_label_second_type_b_array); roiManager("Delete"); //saving ROI overlay save_circleDL_ROIs=roiManager("count"); circle_DL_array=newArray(save_circleDL_ROIs); // saving the list of DL circle ROIs for(i=0; ic_area){ // if the overlapping area is less 80% of the 1circle, no_co = no_co-1; //then, forget that an overlap was identified and move on (restart the loop). //print("Nevermind, It failed 80% overlap. YYYYEEEEEAAAAH"); } else { co_roi_array = Array.concat(co_roi_array, b); //building an array to remember which 1circle ROIs overlap (for ROI selection) co_roi_array_UI = Array.concat(co_roi_array_UI, b2); //building an array to remember which 1circle ROIs overlap (for the human to understand) saved_3circles_array = Array.concat(saved_3circles_array, a); //print("3circles saved so far:"); //Array.print(saved_3circles_array); } } if(b2==(double_label_first_type-multi_b_removed) && (no_co==0)){ //if we have checked every 1circle and still not found a 1circle that overlap (>80%) with the 3circle, roiManager("deselect"); roiManager("Select", a2-1); //move back one spot and select that 3circle, roiManager("Delete"); // then delete it because we know that it was a non-overlapping 3circle and should no longer be considered for colabeling. //print("3circle "+a2+" deleted. AAAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHH"); //3circle ROI death scene. no_overlap=no_overlap+1; // add one to the number of 3circles not overlapping so that we can lower the total 3circles. a=a-1; //remove one 3circles from the counted number of 3circles. Semi repetitive with last variable, but each serve a function in the top IF loop. //wait(5); } if(b2==(double_label_first_type-multi_b_removed) && (no_co==1)){ // if we have checked all 1circles and there was an overlap detected //print("Total "+first_stain_type_TL+" checked: "+bTotal); //then, print # 1circles checked. (next step is to exit loop because a!<(double_label_all_types-no_overlap)). //print("loop = "+n+1); //print("\n"); //wait(5); } if(b2==(double_label_first_type-multi_b_removed) && (no_co>1)){ // if checked all 1circles and there were multiple overlaps, selectWindow(third_image_tif); //select the 8-oxo image run("Clear Results"); roiManager("deselect"); roiManager("Select", a); //select the 3circle ROI roiManager("Measure"); //measure the 3circle ROI so we can... CoM_x_3circle=getResult("XM", 0); // grab the 3circle's center of mass x-coordinate from the results. CoM_y_3circle=getResult("YM", 0); // grab the 3circle's center of mass y-coordinate from the results. CoM_tot_3circle= CoM_x_3circle+CoM_y_3circle; //making the total value (number only used for comparison to 1circles). wait(10); run("Clear Results"); selectWindow(first_image_tif); //select the PV image roiManager("deselect"); roiManager("Select", co_roi_array); //select the overlapping ROIs roiManager("Measure"); wait(5); for(i=0; i0){ print("Removed "+first_stain_type_TL+" ROIs (these were multiple overlaps with "+third_stain_type_TL+" ROIs):"); Array.print(removed_1circles_array); } print(third_stain_type_TL+" saved:"); Array.print(saved_3circles_array); */ roiManager("reset"); ////////////////////////////////////////////// /* In this section we are identifying the 1CIRCLES that have overlapping 3CIRCLES. */ selectWindow(first_image_tif); //select the PV image roiManager("Open", subDir_TL+third_image_TL+third_stain_type_TL+"_vs_"+first_stain_type_TL+"_double-label_ROIoverlay.zip"); double_label_third_type_b = roiManager("count"); double_label_third_type_b_array = Array.getSequence(double_label_third_type_b); //waitForUser(""); roiManager("Open", subDir_TL+first_image_TL+first_stain_type_TL+"_vs_"+third_stain_type_TL+"_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_third_type_b; double_label_first_type_start = double_label_third_type_b; n=0; //count loops no_overlap=0; //number of 1circles without 3circles overlap. co_roi_array2 = newArray(n); // this array will be concatenated with the "d" value for each overlapping 3circle so the ROIs can be selected. co_roi_array2_UI = newArray(n); // this array will be concatenated with the "d2" value for each overlapping 3circle so the user can see multiple overlaps. saved_1circles_array = newArray(n); //building an array to remember which 1circle ROIs overlap (for ROI selection) for(c=double_label_first_type_start; c<(double_label_all_types-no_overlap); c++){ //1circles roiManager("Select", c); c2=c+1; //c2 is a counting variable to correct for the ROI manager starting at ROI #0. //print("1circle = "+c2); dTotal=0; // number of 3circles checked against 1circle "c2". no_co=0; // yes/no variable determining whether overlap was found. for(d=0; dco_area){ // if the overlapping area is less 80% of the 3circle, no_co = no_co-1; //then, forget that an overlap was identified and move on (restart the loop). //print("Nevermind, It failed 80% overlap. YYYYEEEEEAAAAH"); } else { co_roi_array2 = Array.concat(co_roi_array2, d); //building an array to remember which 1circle ROIs overlap (for ROI selection) co_roi_array2_UI = Array.concat(co_roi_array2_UI, d2); //building an array to remember which 1circle ROIs overlap (for the human to understand) saved_1circles_array = Array.concat(saved_1circles_array, c); //building an array to remember which 1circle ROIs overlap (for ROI selection) //print("1Circles saved so far:"); //Array.print(saved_1circles_array); } } if((d2==double_label_third_type_b) && (no_co==0)){ //if checked every 3circle and still not found a 3circle that overlap (>80%) with the 1circle, roiManager("deselect"); wait(10); roiManager("Select", c2-1); roiManager("Delete"); //print("1circle "+c2+" deleted. AAAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHH"); no_overlap=no_overlap+1; // add one to the number of 1circles not overlapping so that we can lower the total 1circles. c=c-1;//remove one 1circle from the counted number of 1circle. Semi repetitive with last variable, but each serve a function in the top IF loop. } } n=n+1; } //waitForUser(""); roiManager("deselect"); roiManager("Select", double_label_third_type_b_array); roiManager("Delete"); //saving ROI overlay save_1circleDL_ROIs=roiManager("count"); circle1_DL_array=newArray(save_1circleDL_ROIs); // saving the list of DL 1circle ROIs for(i=0; i0){ print("Removed "+first_stain_type_TL+" ROIs (these were multiple overlaps with "+third_stain_type_TL+" ROIs):"); Array.print(removed_1circles_array); } */ print(first_stain_type_TL+" DL ROIs = "+save_1circleDL_ROIs); print("\n"+third_image_TL); print(third_stain_type_TL+" DL ROIs = "+save_3circleDL_ROIs); //print("\n"+"Done"); roiManager("reset"); run("Clear Results"); run("_ps_measure_tpl_Background_DL1and2_ROIs"); } //\\//\\//\\//\\//\\//\\//\\ macro "_ps_measure_tpl_Background_DL1and2_ROIs" { //this macro simply recalls the ROIs defined in the last macro in order to measure the values again. wait(50); first_image_tif = first_image_TL+"-2.tif"; second_image_tif = second_image_TL+"-2.tif"; merged_image_tif = merged_image_TL+".tif"; roiManager("Open", subDir_TL+first_image_TL+first_stain_type_TL+"_vs_"+second_stain_type_TL+"_double-label_ROIoverlay.zip"); roiManager("Open", subDir_TL+second_image_TL+second_stain_type_TL+"_vs_"+first_stain_type_TL+"_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. selectWindow(merged_image_tif); 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_TL, second_stain_type_TL, "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_TL) { setTool("oval"); roiManager("reset"); roiManager("Open", subDir_TL+first_image_TL+first_stain_type_TL+"_vs_"+second_stain_type_TL+"_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_TL+first_image_TL+first_stain_type_TL+"_vs_"+second_stain_type_TL+"_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_TL+" double-labeling?", items, 2, 1, "Yes"); Dialog.show; choice = Dialog.getRadioButton; if (choice=="Yes") { setTool("rectangle"); roiManager("reset"); roiManager("Open", subDir_TL+second_image_TL+second_stain_type_TL+"_vs_"+first_stain_type_TL+"_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_TL+second_image_TL+second_stain_type_TL+"_vs_"+first_stain_type_TL+"_double-label_ROIoverlay.zip"); wait(100); roiManager("reset"); run("_ps_measure_tpl_Background_DL1and2_ROIs"); } if (choice=="No, accept double labeling as is.") { //well, aren't you confident. } } if (choice==second_stain_type_TL) { setTool("rectangle"); roiManager("reset"); roiManager("Open", subDir_TL+second_image_TL+second_stain_type_TL+"_vs_"+first_stain_type_TL+"_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_TL+second_image_TL+second_stain_type_TL+"_vs_"+first_stain_type_TL+"_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_TL+" double-labeling?", items, 2, 1, "Yes"); Dialog.show; choice = Dialog.getRadioButton; if (choice=="Yes") { setTool("oval"); roiManager("reset"); roiManager("Open", subDir_TL+first_image_TL+first_stain_type_TL+"_vs_"+second_stain_type_TL+"_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_TL+first_image_TL+first_stain_type_TL+"_vs_"+second_stain_type_TL+"_double-label_ROIoverlay.zip"); wait(100); roiManager("reset"); run("_ps_measure_tpl_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. } } roiManager("reset"); //\\\\\\\\\\\\\ //actually measuring the double labeled ROIs (image 1) run("Clear Results"); selectWindow(first_image_tif); roiManager("Open", subDir_TL+first_image_TL+first_stain_type_TL+"_vs_"+second_stain_type_TL+"_double-label_ROIoverlay.zip"); name = series_name_TL+" "+first_stain_type_TL+" vs "+second_stain_type_TL+" double-label.txt"; DL_ROIs=0; DL_ROIs =roiManager("count"); array=newArray(DL_ROIs); for(i=0; ic_area){ // if the overlapping area is less 80% of the 1v2 ROI, no_co = no_co-1; //then, forget that an overlap was identified and move on (restart the loop). //print("Nevermind, It failed 80% overlap. YYYYEEEEEAAAAH"); } else { co_roi_array = Array.concat(co_roi_array, b); //building an array to remember which 1v2 ROIs overlap (for ROI selection) co_roi_array_UI = Array.concat(co_roi_array_UI, b2); //building an array to remember which 1v2 ROI ROIs overlap (for the human to understand) saved_2v3_array = Array.concat(saved_2v3_array, a); } } if((b2==TL_1v2_type) && (no_co==0)){ //if we have checked every 1v2 ROI and still not found a 1v2 ROI that overlap (>80%) with a 2v3 ROI, roiManager("deselect"); roiManager("Select", a2-1); //move back one spot and select that 2v3 ROI, roiManager("Delete"); // then delete it because we know that it was a non-overlapping 2v3 ROI and should no longer be considered for colabeling. no_overlap=no_overlap+1; // add one to the number of 2v3 ROIs not overlapping so that we can lower the total 2v3 ROIs. a=a-1; //remove one 2v3 ROIs from the counted number of 2v3 ROIs. Semi repetitive with last variable, but each serve a function in the top IF loop. } if(b2==(TL_1v2_type) && (no_co==1)){ // if we have checked all 1v2 ROIs and there was an overlap detected //wait(5); } if(b2==(TL_1v2_type) && (no_co>1)){ // if checked all 1v2 ROIs and there were multiple overlaps, selectWindow(second_image_tif); //select the WFA image run("Clear Results"); roiManager("deselect"); roiManager("Select", a); //select the 2v3 ROI ROI roiManager("Measure"); //measure the 2v3 ROI ROI so we can... CoM_x_2v3_ROI=getResult("XM", 0); // grab the 2v3 ROI's center of mass x-coordinate from the results. CoM_y_2v3_ROI=getResult("YM", 0); // grab the 2v3 ROI's center of mass y-coordinate from the results. CoM_tot_2v3_ROI= CoM_x_2v3_ROI+CoM_y_2v3_ROI; //making the total value (number only used for comparison to 1v2 ROIs). 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; ico_area){ // if the overlapping area is less 80% of the 2v3 ROI, no_co = no_co-1; //then, forget that an overlap was identified and move on (restart the loop). } else { co_roi_array2 = Array.concat(co_roi_array2, d); //building an array to remember which 1v2 ROIs overlap (for ROI selection) co_roi_array2_UI = Array.concat(co_roi_array2_UI, d2); //building an array to remember which 1v2 ROIs overlap (for the human to understand) saved_1v2_ROIs_array = Array.concat(saved_1v2_ROIs_array, c); //building an array to remember which 1v2 ROIs overlap (for ROI selection) } } if((d2==TL_2v3_type_b) && (no_co==0)){ //if checked every 2v3 and still not found a 2v3 ROI that overlap (>80%) with the 1v2 ROI, roiManager("deselect"); roiManager("Select", c2-1); roiManager("Delete"); no_overlap=no_overlap+1; // add one to the number of 1v2 ROIs not overlapping so that we can lower the total 1v2 ROIs. c=c-1;//remove one 1v2 ROI from the counted number of 1v2 ROI. Semi repetitive with last variable, but each serve a function in the top IF loop. } } n=n+1; } roiManager("Select", TL_2v3_type_b_array); roiManager("Delete"); //saving ROI overlay save_1v2_TL_ROIs=roiManager("count"); TL_1v2_ROI_2_array=newArray(save_1v2_TL_ROIs); // saving the list of DL 1v2 ROIs for(i=0; i0){ print("Removed "+first_stain_type_TL+" ROIs (these were multiple overlaps with "+second_stain_type_TL+" ROIs):"); Array.print(removed_1v2_array); } print("1v2 DL ROIs = "+save_1v2_TL_ROIs); print("\n"+second_image_TL); print("2v3 DL ROIs = "+save_2v3_TL_ROIs); roiManager("reset"); run("Clear Results"); /////////////////////////////////// /* In this section we are identifying the 3v2 ROIS that have overlapping 2v3 TL_ROIS. */ selectWindow(merged_image_tif); //select the merged image roiManager("Open", subDir_TL+second_stain_type_TL+"_vs_"+third_stain_type_TL+"_TripleLabel_ROIoverlay.zip"); TL_2v3_type_c = roiManager("count"); TL_2v3_type_c_array = Array.getSequence(TL_2v3_type_c); roiManager("Open", subDir_TL+third_image_TL+third_stain_type_TL+"_vs_"+second_stain_type_TL+"_double-label_ROIoverlay.zip"); TL_2v3and3v2_types = roiManager("count"); TL_2v3and3v2_types_array = Array.getSequence(TL_2v3and3v2_types); TL_3v2_type = TL_2v3and3v2_types-TL_2v3_type_c; TL_3v2_type_start = TL_2v3_type_c; //waitForUser("Starting TL #3"); n=0; //count loops no_overlap=0; //number of 3v2 ROIs without 2v3 ROIs overlap. co_roi_array2 = newArray(n); // this array will be concatenated with the "d" value for each overlapping 2v3 ROI so the ROIs can be selected. co_roi_array2_UI = newArray(n); // this array will be concatenated with the "d2" value for each overlapping 2v3 ROI so the user can see multiple overlaps. saved_3v2_ROIs_array = newArray(n); //building an array to remember which 3v2 ROIs overlap (for ROI selection) for(c=TL_3v2_type_start; c<(TL_2v3and3v2_types-no_overlap); c++){ //3v2 ROIs roiManager("Select", c); c2=c+1; //c2 is a counting variable to correct for the ROI manager starting at ROI #0. dTotal=0; // number of 2v3 ROIs checked against 3v2 ROI "c2". no_co=0; // yes/no variable determining whether overlap was found. for(d=0; dco_area){ // if the overlapping area is less 80% of the 2v3 ROI, no_co = no_co-1; //then, forget that an overlap was identified and move on (restart the loop). } else { co_roi_array2 = Array.concat(co_roi_array2, d); //building an array to remember which 3v2 ROIs overlap (for ROI selection) co_roi_array2_UI = Array.concat(co_roi_array2_UI, d2); //building an array to remember which 3v2 ROIs overlap (for the human to understand) saved_3v2_ROIs_array = Array.concat(saved_3v2_ROIs_array, c); //building an array to remember which 3v2 ROIs overlap (for ROI selection) } } //print("overlap"); if((d2==TL_2v3_type_c) && (no_co==0)){ //if checked every 2v3 ROI and still not found a 2v3 ROI that overlap (>80%) with the 3v2 ROI, roiManager("deselect"); roiManager("Select", c2-1); roiManager("Delete"); no_overlap=no_overlap+1; // add one to the number of 3v2 ROIs not overlapping so that we can lower the total 3v2 ROIs. c=c-1;//remove one 3v2 ROI from the counted number of 3v2 ROIs. Semi repetitive with last variable, but each serve a function in the top IF loop. } } n=n+1; } //waitForUser("finished TL #3"); roiManager("Select", TL_2v3_type_c_array); roiManager("Delete"); //waitForUser(""); //saving ROI overlay save_3v2_TL_ROIs=roiManager("count"); TL_3v2_ROI_2_array=newArray(save_3v2_TL_ROIs); // saving the list of TL 3v2 ROIs for(i=0; i