//Macro developed by Cameron J. Nowell of Monash University (cameron.nowell@monash.edu) based orginal algorithm //developed to measure worm and fly larvae movement for drug screening. //Code will take ND2 files captured on a Nikon microscope and measure the degree of movement // //Requirements - Standard install of Fiji and BAR plugin //Assumptions // - Data is captured using a monochrome camera on a Nikon microscope // - All time segments are the same length // - There is a baseline capture that one other capture is compared back to fs=File.separator; roiManager("reset"); run("Clear Results"); //build manual arrays for dialog pull down menus for scale and sampling window sizes scaleItems=newArray(32,4,8,16,64,128); windowItems=newArray(25,10,50,75,100); //create dialog box to collect configuration requiremnts for the analysis Dialog.create("Analysis Settings"); Dialog.addMessage("\n\nExperiment Details", 16); Dialog.addString("Experiment Name", "Test"); Dialog.addString("Segment One Name", "Baseline"); Dialog.addString("Segment Two Name", "Two"); //Dialog.addString("Segment Three Name", "Three"); Dialog.addMessage("\n\nAnalysis Details", 16); Dialog.addChoice("Scaling Level for Final Image", scaleItems); Dialog.addChoice("Window Sampling Size for Heat Map Movie", windowItems); Dialog.addNumber("Frames to Skip at Segment Start", 30); Dialog.addNumber("Frames to Extract Per Segment", 150); Dialog.show(); //store values from dialog box in custom varialbles expName=Dialog.getString(); stimOne=Dialog.getString(); stimTwo=Dialog.getString(); //stimThree=Dialog.getString(); scaleNumber=Dialog.getChoice(); windowSize=Dialog.getChoice(); segSkip=Dialog.getNumber(); segWidth=Dialog.getNumber(); //create array list to store image names in stimList=newArray(stimOne,stimTwo); //prompt user to select first file in the in the time series firstFile=File.openDialog("Select First File In Image Sequence"); run("Bio-Formats Macro Extensions"); run("Bio-Formats Importer", "open=["+firstFile+"] autoscale color_mode=Default rois_import=[ROI manager] specify_range view=Hyperstack stack_order=XYCZT t_begin=1 t_end=1 t_step=1"); //open first file, store dimensions and get timng data from meta data. //open(firstFile); nameStore=getTitle; getDimensions(width, height, channels, slices, frames); //time=Stack.getFrameInterval(); time=1; //create output directories for path of opened file for ROIs, Heat Maps, Data Sheets and Movies dir=File.getParent(firstFile)+fs; roiDir=dir+"ROIs"+fs; File.makeDirectory(roiDir); heatMapDir=dir+"Heat Maps"+fs; File.makeDirectory(heatMapDir); dataDir=dir+"Data"+fs; File.makeDirectory(dataDir); movieDir=dir+"Movies"+fs; File.makeDirectory(movieDir); roiPath=roiDir+"Tissue Outline.roi"; //scale the first frame of the time series based on the selected scale number run("Scale...", "x=- y=- z=1.0 width="+(width/scaleNumber)+" height="+(height/scaleNumber)+" depth="+slices+" interpolation=None process create title=Scaled"); selectWindow("Scaled"); run("Set... ", "zoom=1600 x="+((width/scaleNumber)/2)+" y="+((height/scaleNumber)/2)); //set wand tool and ask user to click on the tissue to use it for a mask. setTool("wand"); run("Wand Tool...", "tolerance=4500 mode=Legacy"); waitForUser("Click Tissue"); roiManager("Add"); roiManager("Save", roiDir+expName+" - Tissue Outline.roi"); roiManager("reset"); selectWindow("Scaled"); run("Close"); run("Close All"); //generate data tables for recording data tableTitle="[Raw Standard Deviation Values]"; if (isOpen("Raw Standard Deviation Values")){ print("Table already open");} else{ run("Table...", "name="+tableTitle+" width=1200 height=250"); print(tableTitle, "\\Headings:Experiment Name\tStimulation Type\tScale Level\tPixel ID\tStandard Deviation"); } tableTitle2="[Standard Deviation Scoring]"; if (isOpen("Standard Deviation Scoring")){ print("Table already open");} else{ run("Table...", "name="+tableTitle2+" width=1200 height=250"); print(tableTitle2, "\\Headings:Experiment Name\tStimulation Type\tScale Level\tTotal Pixels Measured\tCount >2 Std Deviations\tCount Between 1 and 2 Std Deviations\tCount Between 1 and 0 Std Deviations\tPercent >2 Std Deviations\tPercent Between 1 and 2 Std Deviations\tPercent Between 1 and 0 Std Deviations"); } tableTitle3="[Deviation Relative Change]"; if (isOpen("Deviation Relative Change")){ print("Table already open");} else{ run("Table...", "name="+tableTitle3+" width=1200 height=250"); print(tableTitle3, "\\Headings:Experiment Name\tScale Level\tPixel ID\t"+stimList[1]+" Fold Change to "+stimList[0]+"\tFold Change Direction Relative to "+stimList[0]+"\tFold Change Direction Relative to Previous Stimulation"); } tableTitle4="[Deviation Relative Change - Rolling Average]"; if (isOpen("Deviation Relative Change - Rolling Average")){ print("Table already open");} else{ run("Table...", "name="+tableTitle4+" width=1200 height=250"); print(tableTitle4, "\\Headings:Experiment Name\tScale Level\tPixel ID\t"+stimList[1]+" Fold Change to "+stimList[0]+"\tFold Change Direction Relative to "+stimList[0]+"\tFold Change Direction Relative to Previous Stimulation"); } run("Set Measurements...", "mean standard min limit redirect=None decimal=3"); //load image sequence and change image name to the user defined experiment name print("Loading Image Sequence"); //open("C:/Users/camer/Desktop/Film2.tif"); run("Bio-Formats Importer", "open=["+firstFile+"] autoscale color_mode=Default rois_import=[ROI manager] view=Hyperstack stack_order=XYCZT"); rename(expName); getDimensions(width, height, channels, slices, frames); run("Properties...", "frame=1"); //reset ROI manager and results roiManager("reset"); roiManager("Show All"); run("Clear Results"); //Use BAR plugin to find dark frames representing additions. print("Finding Addition Points"); title="Plot Values"; run("Plot Z-axis Profile"); run("Find Peaks", "min._peak_amplitude=12.50 min._peak_distance=0 min._value=[] max._value=[] list"); segEnds=newArray((Table.get("X2", 0, title)),((Table.get("X2", 1, title)))); Array.sort(segEnds); selectWindow(title); run("Close"); selectWindow(expName+"-0-0"); close(); selectWindow("Peaks in "+expName+"-0-0"); close(); setBatchMode(true); //extract segments based on black frame locations. Name segments from suer entered values in the initial dialog. print("Extracting Segments"); selectWindow(expName); print("Extracting "+stimOne+" Segment - Planes "+segSkip+" to "+(segSkip+segWidth-1)); run("Duplicate...", "title=["+stimOne+"] duplicate range="+segSkip+"-"+(segSkip+segWidth-1)); selectWindow(expName); print("Extracting "+stimTwo+" Segment - Planes "+(segEnds[0]+segSkip)+" to "+(segEnds[0]+(segSkip+segWidth-1))); run("Duplicate...", "title=["+stimTwo+"] duplicate range="+(segEnds[0]+segSkip)+"-"+(segEnds[0]+(segSkip+segWidth-1))); //selectWindow(expName); //print("Extracting "+stimThree+" Segment - Planes "+(segEnds[1]+segSkip)+" to "+(segEnds[1]+(segSkip+segWidth-1))); //run("Duplicate...", "title=["+stimThree+"] duplicate range="+(segEnds[1]+segSkip)+"-"+(segEnds[1]+(segSkip+segWidth-1))); selectWindow(expName); close(); for(s=0;s0){ stdDevArray=Array.concat(stdDevArray, mean); if(mean>(stdDev*2)){ greaterThan2Std=Array.concat(greaterThan2Std, mean); } if(mean<(stdDev*2)){ if(mean>stdDev){ between1and2Std=Array.concat(between1and2Std, mean); } else{ lessThan1Std=Array.concat(lessThan1Std, mean); } } } } //print all meassured std devs into table for(a=0;a0){ selectWindow(oneName); roiManager("select", r); run("Measure"); oneMean=getResult("Mean"); foldArrayOne=Array.concat(foldArrayOne, oneMean); //selectWindow(twoName); //roiManager("select", r); //run("Measure"); //twoMean=getResult("Mean"); //foldArrayTwo=Array.concat(foldArrayTwo, twoMean); //selectWindow(threeName); //roiManager("select", r); //run("Measure"); //threeMean=getResult("Mean"); //foldArrayThree=Array.concat(foldArrayThree, threeMean); toStartDirectionString=""; toPreviousDirectionString=""; if(oneMean<1){ toStartDirectionString=toStartDirectionString+"0"; toPreviousDirectionString=toPreviousDirectionString+"0"; }else{ toStartDirectionString=toStartDirectionString+"1"; toPreviousDirectionString=toPreviousDirectionString+"1"; } //if(oneMean>threeMean){ // toStartDirectionString=toStartDirectionString+"0"; //}else{ // toStartDirectionString=toStartDirectionString+"1"; //} //if(twoMean>threeMean){ // toPreviousDirectionString=toPreviousDirectionString+"0"; //}else{ // toPreviousDirectionString=toPreviousDirectionString+"1"; //} upDownArrayBase=Array.concat(upDownArrayBase, toStartDirectionString); upDownArraySequential=Array.concat(upDownArraySequential, toPreviousDirectionString); } } for(p=0;p0){ selectWindow(oneName); roiManager("select", r); run("Measure"); oneMean=getResult("Mean"); foldArrayOneRolling=Array.concat(foldArrayOneRolling, oneMean); //selectWindow(twoName); //roiManager("select", r); //run("Measure"); //twoMean=getResult("Mean"); //foldArrayTwoRolling=Array.concat(foldArrayTwoRolling, twoMean); //selectWindow(threeName); //roiManager("select", r); //run("Measure"); //threeMean=getResult("Mean"); //foldArrayThreeRolling=Array.concat(foldArrayThreeRolling, threeMean); toStartDirectionString=""; toPreviousDirectionString=""; if(oneMean<1){ toStartDirectionString=toStartDirectionString+"0"; toPreviousDirectionString=toPreviousDirectionString+"0"; }else{ toStartDirectionString=toStartDirectionString+"1"; toPreviousDirectionString=toPreviousDirectionString+"1"; } //if(oneMean>threeMean){ // toStartDirectionString=toStartDirectionString+"0"; //}else{ // toStartDirectionString=toStartDirectionString+"1"; //} //if(twoMean>threeMean){ // toPreviousDirectionString=toPreviousDirectionString+"0"; //}else{ // toPreviousDirectionString=toPreviousDirectionString+"1"; //} upDownArrayBaseRolling=Array.concat(upDownArrayBaseRolling, toStartDirectionString); upDownArraySequentialRolling=Array.concat(upDownArraySequentialRolling, toPreviousDirectionString); } } for(p=0;p