//These macros were written by Steve Rothery
//FILM - Facility for Imaging in Light Microscopy, Imperial College London
//http://www3.imperial.ac.uk/imagingfacility/

////////////////////////////////////////////////////////////////1

macro "Radial ROI Creation and Intensity Profiles Action Tool - C000 L08h8 L808h L22ee L2ee2 "
{

run("Set Measurements...", "area mean min centroid feret's display redirect=None decimal=2");

//initialise
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
roiManager("reset");
run("Clear Results");
run("Select None");

//dialogue
Dialog.create("Options");
Dialog.addCheckbox("Draw line length on image", true);
Dialog.addNumber("or enter line length in "+unit, 50);
Dialog.addNumber("Line Angle (divide into 360)", 30);
Dialog.addCheckbox("Plot line intensity profiles and create data table", true);
Dialog.show();

Draw_line=Dialog.getCheckbox();
Line_length=Dialog.getNumber();
angle_inc=Dialog.getNumber();
data_out=Dialog.getCheckbox();
Plot_Max=0;


//mark centre
setTool("point");
waitForUser("","Mark centre \n then press ok");
roiManager("add");
roiManager("select", 0);
roiManager("rename", "Centre Point");
roiManager("measure");
//get centre
X_centre=getResult("X", 0)/px;
Y_centre=getResult("Y", 0)/py;
roiManager("Show None");
run("Clear Results");
run("Select None");

setTool("line");
if (Draw_line==true){
	selectWindow(fn);
	run("Select None");	
	waitForUser("","Draw line length \n then press ok");
	if (selectionType==5){	
	run("Measure");
	Line_length=getResult("Length", 0);
	run("Clear Results");
	}else Line_length=50;
}




//draw lines
for (angle=0;angle<360;angle+=angle_inc){
//convert to radians and calculate x and y end position
an=angle*0.0174533;
x2=cos(an)*Line_length/px;
y2=sin(an)*Line_length/px;
makeLine(X_centre, Y_centre, X_centre+x2, Y_centre+y2);
roiManager("Add");
}
n=roiManager("count");
for (roi=1;roi<n;roi++){
roiManager("select", roi);
roiManager("rename", "Line "+roi);
}
selectWindow(fn);
roiManager("Show All without labels");

if (data_out==true){
//get line intensity data and create results table
res_length=newArray(n-1);
for (roi=1;roi<n;roi++){
selectWindow(fn);
roiManager("select", roi);
run("Plot Profile");
Plot.getValues(X_Values, Y_points);
close();
Table.setColumn("Line "+roi, Y_points);
res_length[roi-1]=Y_points.length;
Array.getStatistics(Y_points, min, P_max, mean, stdDev);
if (P_max>Plot_Max){
	Plot_Max=P_max;
}
}


//get mean intensity
nres=nResults;

Mean_Line_Intesity=newArray(nres);
Stand_Error=newArray(nres);
len=(nres-1)*px;
for (res=0;res<nres;res++){
	temp_Res_Rows=newArray(n-1);
	n_per_line=0;
for (roi=1;roi<n;roi++){
	if (res<res_length[roi-1]){
	temp_Res_Rows[roi-1]=getResult("Line "+roi, res);		
	Mean_Line_Intesity[res]=Mean_Line_Intesity[res]+getResult("Line "+roi, res);
	n_per_line=n_per_line+1;
	}
	
}

Mean_Line_Intesity[res]=Mean_Line_Intesity[res]/n_per_line;
temp_Res_Rows=Array.deleteValue(temp_Res_Rows, 0);
Array.getStatistics(temp_Res_Rows, temp_Res_min, temp_Res_max, temp_Res_mean, temp_Res_stdDev);
Stand_Error[res]=temp_Res_stdDev/sqrt(temp_Res_Rows.length);
}
Table.setColumn("Mean", Mean_Line_Intesity);
Table.setColumn("Standard Error (Std/Sqrt(n)", Stand_Error);
Array.getStatistics(Mean_Line_Intesity, Mean_min, Mean_max, Mean_mean, Mean_stdDev);

//plot line profiles
Plot.create(fn+" Intensity Line Profiles", "Distance ("+unit+")", "Intensity", X_Values, Mean_Line_Intesity)
Plot.setLimits (0, len, 0, Plot_Max*1.2);
Plot.setFrameSize (400, 200);
Plot.setColor ("blue", "red");
Plot.setLineWidth (1);
for (roi=1;roi<n;roi++){
Plot.add ("line", X_Values, Table.getColumn("Line "+roi));
}
Plot.show ();

//plot mean intensity
Plot.create(fn+" Mean Intensity Line Profile", "Distance ("+unit+")", "Intensity", X_Values, Mean_Line_Intesity)
Plot.setLimits (0, len, 0, Mean_max*1.2);
Plot.setFrameSize (400, 200);
Plot.setColor ("blue", "red");
Plot.setLineWidth (1);
Plot.add ("line", X_Values, Mean_Line_Intesity)
Plot.add("error bars", Stand_Error);
Plot.show ();

Table.rename("Results", fn+" Data");
}
}


//////////////////////////////////////////2

macro "Radial ROI Creation from mask and Intensity Profiles Action Tool - C000 L08h8 L808h L22ee L2ee2 Ceee V5577 C00g O5577"
{

run("Set Measurements...", "area mean min centroid feret's display redirect=None decimal=2");

//initialise
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
roiManager("reset");
run("Clear Results");
run("Select None");

//dialogue
Dialog.create("Options");
Dialog.addCheckbox("Draw line length on image", true);
Dialog.addNumber("or enter line length in "+unit, 50);
Dialog.addNumber("Line Angle (divide into 360)", 30);
Dialog.addCheckbox("Plot line intensity profiles and create data table", true);
Dialog.show();

Draw_line=Dialog.getCheckbox();
Line_length=Dialog.getNumber();
angle_inc=Dialog.getNumber();
data_out=Dialog.getCheckbox();
Plot_Max=0;
region=1;


//draw shape
setTool("oval");
waitForUser("","Draw roi shape \n then press ok");
roiManager("add");
roiManager("Show All without labels");
//draw line

setTool("line");
if (Draw_line==true){
	selectWindow(fn);
	run("Select None");	
	waitForUser("","Draw line length \n then press ok");
	if (selectionType==5){	
	run("Measure");
	Line_length=getResult("Length", 0);
	run("Clear Results");
	}else Line_length=50;
}

//create ring roi
roiManager("select", 0);
roiManager("rename", "Centre ROI");
roiManager("measure");
run("Enlarge...", "enlarge="+Line_length);
roiManager("add");
roiManager("Select", newArray(0,1));
roiManager("XOR");
roiManager("Add");
roiManager("deselect");
roiManager("Select", 1);
roiManager("delete");
roiManager("Select", 1);
roiManager("rename", "Ring ROI");


//get centre
X_centre=getResult("X", 0)/px;
Y_centre=getResult("Y", 0)/py;
Measures=newArray("Area", "Feret", "Min Feret");
Ring=newArray(3);
Ring[0]=getResult("Area", 0);
Ring[1]=getResult("Feret", 0);
Ring[2]=getResult("MinFeret", 0);
full_line=Line_length+Ring[1];

run("Clear Results");
run("Select None");

//draw lines
for (angle=0;angle<360;angle+=angle_inc){
//convert to radians and calculate x and y end position
an=angle*0.0174533;
x2=cos(an)*(full_line)/px;
y2=sin(an)*(full_line)/px;
makeLine(X_centre, Y_centre, X_centre+x2, Y_centre+y2);
roiManager("Add");
}


//make new shortened line
n=roiManager("count");
res_length=newArray(n-2);
for (roi=2;roi<n;roi++){
	roiManager("select", roi);
	newline(Line_length);
}


//delete original lines
for (roi=2;roi<n;roi++){
roiManager("Select", 2);
roiManager("delete");
}

n=roiManager("count");
for (roi=2;roi<n;roi++){
roiManager("select", roi);
roiManager("rename", "Line "+roi-1);
}
selectWindow(fn);
roiManager("Show All without labels");


if (data_out==true){
//get line intensity data and create results table
for (roi=0;roi<n-2;roi++){
selectWindow(fn);
roiManager("select", roi+2);
run("Plot Profile");
Plot.getValues(X_Values, Y_points);
close();
Table.setColumn("Line "+roi+1, Y_points);
res_length[roi]=Y_points.length;
Array.getStatistics(Y_points, min, P_max, mean, stdDev);
if (P_max>Plot_Max){
	Plot_Max=P_max;
}
}


//get mean intensity
nres=nResults;
Mean_Line_Intesity=newArray(nres);
Stand_Error=newArray(nres);
len=(nres-1)*px;

for (res=0;res<nres;res++){
	temp_Res_Rows=newArray(n-2);
	n_per_line=0;
for (roi=0;roi<n-2;roi++){
	if (res<res_length[roi]){
	temp_Res_Rows[roi]=getResult("Line "+roi+1, res);		
	Mean_Line_Intesity[res]=Mean_Line_Intesity[res]+getResult("Line "+roi+1, res);
	n_per_line=n_per_line+1;
	}
}

Mean_Line_Intesity[res]=Mean_Line_Intesity[res]/n_per_line;
temp_Res_Rows=Array.deleteValue(temp_Res_Rows, 0);
Array.getStatistics(temp_Res_Rows, temp_Res_min, temp_Res_max, temp_Res_mean, temp_Res_stdDev);
Stand_Error[res]=temp_Res_stdDev/sqrt(temp_Res_Rows.length);
}
Table.setColumn("Mean", Mean_Line_Intesity);
Table.setColumn("Standard Error (Std/Sqrt(n)", Stand_Error);
Array.getStatistics(Mean_Line_Intesity, Mean_min, Mean_max, Mean_mean, Mean_stdDev);



//plot line profiles
Plot.create(fn+" Intensity Line Profiles", "Distance ("+unit+")", "Intensity", X_Values, Mean_Line_Intesity)
Plot.setLimits (0, len, 0, Plot_Max*1.2);
Plot.setFrameSize (400, 200);
Plot.setColor ("blue", "red");
Plot.setLineWidth (1);
for (roi=0;roi<n-2;roi++){
Plot.add ("line", X_Values, Table.getColumn("Line "+roi+1));
}
Plot.show ();


//plot mean intensity
Plot.create(fn+" Mean Intensity Line Profile", "Distance ("+unit+")", "Intensity", X_Values, Mean_Line_Intesity)
Plot.setLimits (0, len, 0, Mean_max*1.2);
Plot.setFrameSize (400, 200);
Plot.setColor ("blue", "red");
Plot.setLineWidth (1);
Plot.add ("line", X_Values, Mean_Line_Intesity)
Plot.add("error bars", Stand_Error);
Plot.show ();

//add to results table
Table.setColumn("Roi Measurements", Measures);
Table.setColumn("Roi Values", Ring);
Table.rename("Results", fn+" Data");


// restrict line to roi
function newline(Line_length){
Roi.getContainedPoints(Roi_Xpoints, Roi_Ypoints);
roiManager("select", region);
for (pt=0;pt<Roi_Xpoints.length;pt++){
	if (selectionContains(Roi_Xpoints[pt], Roi_Ypoints[pt])==false){
		Roi_Xpoints[pt]=-1;
		Roi_Ypoints[pt]=-1;
	}
}
Roi_Xpoints=Array.deleteValue(Roi_Xpoints, -1);
Roi_Ypoints=Array.deleteValue(Roi_Ypoints, -1);
line_len=(Roi_Xpoints.length)-1;
makeLine(Roi_Xpoints[0], Roi_Ypoints[0], Roi_Xpoints[line_len], Roi_Ypoints[line_len]);
roiManager("add");
}

}
}

//////////////////////////////////////////3

macro "Radial line and quadrant Creation Action Tool - C000 L08h8 L808h L22ee L2ee2 L0822 L2280 L80e2 Le2h8 Lh8ee Lee8h Lbh2e L2e08"
{

run("Set Measurements...", "area mean min centroid feret's display redirect=None decimal=2");

//initialise
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
roiManager("reset");
run("Clear Results");
run("Select None");


//dialogue
Dialog.create("Options");
Dialog.addCheckbox("Draw line length on image", true);
Dialog.addNumber("or enter line length in "+unit, 50);
Dialog.addNumber("Line Angle (divide into 360)", 30);
Dialog.show();

Draw_line=Dialog.getCheckbox();
Line_length=Dialog.getNumber();
angle_inc=Dialog.getNumber();



//mark centre
setTool("point");
waitForUser("","Mark centre \n then press ok");
roiManager("add");
roiManager("select", 0);
roiManager("rename", "Centre Point");
roiManager("measure");
//get centre
X_centre=getResult("X", 0)/px;
Y_centre=getResult("Y", 0)/py;
roiManager("Show None");
run("Clear Results");
run("Select None");

setTool("line");
if (Draw_line==true){
	selectWindow(fn);
	run("Select None");	
	waitForUser("","Draw line length \n then press ok");
	if (selectionType==5){	
	run("Measure");
	Line_length=getResult("Length", 0);
	run("Clear Results");
	}else Line_length=50;
}



//create lines
for (angle=0;angle<360;angle+=angle_inc){
if (angle>90){
	dir=-1;
}
//convert to radians and calculate x and y end position
an=angle*0.0174533;
x2=cos(an)*Line_length/px;
y2=sin(an)*Line_length/px;
makeLine(X_centre, Y_centre, X_centre+x2, Y_centre+y2);
roiManager("Add");
}

n=roiManager("count");
for (roi=1;roi<n;roi++){
roiManager("select", roi);
roiManager("rename", "Line "+roi);
}


//create boxes
for (roi=1;roi<n;roi++){
roiManager("select", roi);
getSelectionCoordinates(xpt1, ypt1);
roiManager("select", roi+1);
getSelectionCoordinates(xpt2, ypt2);
makePolygon(xpt1[0], ypt1[0], xpt1[1], ypt1[1], xpt2[1], ypt2[1]);
roiManager("add");
}
n2=roiManager("count");
for (roi=n;roi<n2;roi++){
roiManager("select", roi);
roiManager("rename", "Region "+roi-n+1);
}

selectWindow(fn);
roiManager("Show All without labels");

}

///////////////////////////////////////////////////////////////4

macro "Radial Line and Quadrants from Mask Action Tool - C000 L08h8 L808h L22ee L2ee2 L0822 L2280 L80e2 Le2h8 Lh8ee Lee8h Lbh2e L2e08 Ceee V5577 C00g O5577"
{

run("Set Measurements...", "area mean min centroid feret's display redirect=None decimal=2");

//initialise
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
roiManager("reset");
run("Clear Results");
run("Select None");
region=0;

//dialogue
Dialog.create("Options");
Dialog.addCheckbox("Draw line length on image", true);
Dialog.addNumber("or enter line length in "+unit, 50);
Dialog.addNumber("Line Angle (divide into 360)", 30);
Dialog.show();

Draw_line=Dialog.getCheckbox();
Line_length=Dialog.getNumber();
angle_inc=Dialog.getNumber();

//draw shape
setTool("oval");
waitForUser("","Draw roi shape \n then press ok");
roiManager("add");
roiManager("Show All without labels");

setTool("line");
if (Draw_line==true){
	selectWindow(fn);
	run("Select None");	
	waitForUser("","Draw line length \n then press ok");
	if (selectionType==5){	
	run("Measure");
	Line_length=getResult("Length", 0);
	run("Clear Results");
	}else Line_length=50;
}


//create ring roi
roiManager("select", 0);
roiManager("measure");
roiManager("rename", "Centre Point");
run("Enlarge...", "enlarge="+Line_length);
roiManager("add");
roiManager("Select", newArray(0,1));
roiManager("XOR");
roiManager("Add");
roiManager("Select", newArray(0,1));
roiManager("delete");
roiManager("select", 0);
roiManager("rename", "Ring ROI");


//get centre
X_centre=getResult("X", 0)/px;
Y_centre=getResult("Y", 0)/py;
circle_width=getResult("Feret", 0);
full_line=Line_length+circle_width;

run("Clear Results");
run("Select None");

//draw lines
for (angle=0;angle<360;angle+=angle_inc){
//convert to radians and calculate x and y end position
an=angle*0.0174533;
x2=cos(an)*(full_line)/px;
y2=sin(an)*(full_line)/px;
makeLine(X_centre, Y_centre, X_centre+x2, Y_centre+y2);
roiManager("Add");
}

n=roiManager("count");
for (roi=1;roi<n;roi++){
roiManager("select", roi);
roiManager("rename", "Line "+roi);
}


//create boxes
for (roi=1;roi<n;roi++){
roiManager("select", roi);
getSelectionCoordinates(xpt1, ypt1);
roiManager("select", roi+1);
getSelectionCoordinates(xpt2, ypt2);
makePolygon(xpt1[0], ypt1[0], xpt1[1], ypt1[1], xpt2[1], ypt2[1], xpt2[0], ypt2[0]);
roiManager("add");
}

for (roi=0;roi<n-1;roi++){
roiManager("Select", newArray(0,n));
roiManager("AND");
roiManager("add");
roiManager("deselect");
roiManager("select", n);
roiManager("delete");
}

for (roi=0;roi<n-1;roi++){
roiManager("deselect");
roiManager("select", 1);
roiManager("delete");
}


for (roi=1;roi<n;roi++){
roiManager("select", roi);
roiManager("rename", "Region "+roi);
}

selectWindow(fn);
roiManager("Show All without labels");

}


///////////////////////////////////////////////////////////5

macro "Multiple Ring ROI Creation Action Tool - C000 O00gg O22cc O4488"
{

run("Set Measurements...", "area mean min centroid feret's display redirect=None decimal=2");

//initialise
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
roiManager("reset");
run("Clear Results");
run("Select None");

//dialogue
Dialog.create("Options");
Dialog.addNumber("Ring Width in "+unit, 10);
Dialog.addNumber("Number of rings", 5);
Dialog.addCheckbox("Delete Full Regions after Rings are Created", false);
Dialog.show();

Ring_Width=Dialog.getNumber();
Ring_Width=Ring_Width/px;
Ring_Number=Dialog.getNumber();
Delete_Regions=Dialog.getCheckbox();

//Draw or mark centre region
setTool("oval");
waitForUser("","Draw or mark centre region \n then press ok");
roiManager("add");

//create full regions
for (ring=1;ring<=Ring_Number;ring++){
roiManager("select", 0);
roiManager("rename", "Centre region");
	run("Enlarge...", "enlarge="+Ring_Width*px*ring);
	roiManager("add");
}

//create ring regions
n=roiManager("count");
for (ring=0;ring<n-1;ring++){
roiManager("Select", newArray(ring,ring+1));
roiManager("XOR");
roiManager("Add");
}

//rename full regions
for (ring=0;ring<n-1;ring++){
roiManager("Select", ring+1);
roiManager("rename", "Full Region "+ring+1);
}

//rename ring regions
n2=roiManager("count");
for (roi=n;roi<n2;roi++){
roiManager("select", roi);
roiManager("rename", "Ring Region "+roi-n+1);
}

//delete full regions
if (Delete_Regions==true){
for (ring=0;ring<n-1;ring++){
roiManager("Select", 1);
roiManager("delete");
}
}

selectWindow(fn);
roiManager("Show All without labels");
}


//////////////////////////////////////////6

macro "Create Boxes Along a Line Action Tool - C000 L0ba8 La8ha C00g R0639 R3539 R6439 R9339 Rc439 Rf539"
{

//run("Set Measurements...", "area mean min centroid display redirect=None decimal=3");
run("Set Measurements...", "area mean min centroid display redirect=None decimal=3");
roiManager("reset");
run("Select None");
run("Clear Results");

fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);

Dialog.create("Options");
Dialog.addRadioButtonGroup("Line Type", newArray("line","freeline"), 1, 2, "freeline");
Dialog.addCheckbox("Draw Box dimensions", true);
Dialog.addNumber("or use box width in "+unit, 20);
Dialog.addNumber("and box height in "+unit, 20);
Dialog.addCheckbox("Boxes angled to follow line", false);
Dialog.show();

line_type=Dialog.getRadioButton();
draw_box=Dialog.getCheckbox();
boxwidth=Dialog.getNumber();
boxheight=Dialog.getNumber();
Angled=Dialog.getCheckbox();

//draw path
setTool(line_type);
waitForUser("Draw path left to right\n then press OK");
if (selectionType==-1){
	exit("No line drawn");
}
run("Interpolate", "interval=1 smooth adjust");
roiManager("add")
getSelectionCoordinates(xpoints, ypoints);


//draw box height
if (draw_box==true){
	setTool("rectangle");
	selectWindow(fn);
	run("Select None");	
	waitForUser("Draw box \n then press OK");
	if (selectionType==0){	
	getSelectionBounds(box_x, box_y, boxwidth, boxheight);
	}else {
		box_width=20;
		boxheight=20;
	}
}


//polygon arrays
Box_lines=floor(xpoints.length/boxwidth)+1;
polyX1=newArray(Box_lines+1);
polyX2=newArray(Box_lines+1);
polyY1=newArray(Box_lines+1);
polyY2=newArray(Box_lines+1);


//get centres x and y
X_centre=newArray(Box_lines+1);
Y_centre=newArray(Box_lines+1);
for (roi=0;roi<Box_lines;roi++){
X_centre[roi]=xpoints[roi*boxwidth];
Y_centre[roi]=ypoints[roi*boxwidth];
makePoint(X_centre[roi], Y_centre[roi], "hybrd");
}


//create first line on the left
makeLine(X_centre[0]-boxwidth/2, Y_centre[0]-boxheight/2, X_centre[0]-boxwidth/2, Y_centre[0]+boxheight/2);
if (Angled==true){
rot=atan2(Y_centre[0]-Y_centre[1],X_centre[0]-X_centre[1])*180/PI;
run("Rotate...", "  angle=rot");
}
getLine(newx1, newy1, newx2, newy2, lineWidth);
polyX1[0]=newx1;
polyY1[0]=newy1;
polyX2[0]=newx2;
polyY2[0]=newy2;

//create middle lines
for (i=1;i<Box_lines;i++){
makeLine(X_centre[i]-boxwidth/2, Y_centre[i]-boxheight/2 , X_centre[i]-boxwidth/2, Y_centre[i]+boxheight/2);
if (Angled==true){
rot=atan2(Y_centre[i-1]-Y_centre[i],X_centre[i-1]-X_centre[i])*180/PI;
run("Rotate...", "  angle=rot");
}
getLine(newx1, newy1, newx2, newy2, lineWidth);
polyX1[i]=newx1;
polyY1[i]=newy1;
polyX2[i]=newx2;
polyY2[i]=newy2;
}

//create last line on right
makeLine(X_centre[Box_lines-1]+boxwidth/2, Y_centre[Box_lines-1]-boxheight/2, X_centre[Box_lines-1]+boxwidth/2, Y_centre[Box_lines-1]+boxheight/2);
if (Angled==true){
rot=atan2(Y_centre[Box_lines-2]-Y_centre[Box_lines-1],X_centre[Box_lines-2]-X_centre[Box_lines-1])*180/PI;
run("Rotate...", "  angle=rot");
}
getLine(newx1, newy1, newx2, newy2, lineWidth);
polyX1[Box_lines]=newx1;
polyY1[Box_lines]=newy1;
polyX2[Box_lines]=newx2;
polyY2[Box_lines]=newy2;	


setTool("rectangle");

//make polygons
for (poly=0;poly<Box_lines;poly++){
makePolygon(polyX1[poly], polyY1[poly], polyX2[poly], polyY2[poly], polyX2[poly+1], polyY2[poly+1], polyX1[poly+1], polyY1[poly+1]);
roiManager("add");	
}


//rename rois
n=roiManager("count");
roiManager("select", 0);
	roiManager("rename", "Original Line");
for (roi=1;roi<n;roi++){
	roiManager("select", roi);
	roiManager("rename", "Roi "+roi);
}

//measure
run("Clear Results");
roiManager("deselect");
roiManager("measure");


//finish up
selectWindow(fn);
roiManager("Show All without labels");
}


/////////////////////////////////////////////////////////7

macro "Create ROI's from points Action Tool - Cg00 V3322 Vc722 V5c22 C00g O0077 O9477 O2977"
{
	

fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
shape="";
n=0;


selection_method=newArray("From Maxima","From Multi-point","From ROI Manager");
Sel_Type=newArray("rectangle","oval");	

Dialog.create("Options");
Dialog.addRadioButtonGroup("Point selection method", selection_method, 1, 2, selection_method[0]);
Dialog.addRadioButtonGroup("ROI shape", Sel_Type, 1, 2, Sel_Type[1]);
Dialog.addNumber("ROI Width ("+unit+")", 15);
Dialog.addNumber("ROI Height ("+unit+")", 15);
Dialog.addCheckbox("keep existing ROI's", false);

Dialog.show();

sel_meth=Dialog.getRadioButton();
sel_typ=Dialog.getRadioButton();
Roi_width=Dialog.getNumber();
Roi_height=Dialog.getNumber();
keep_roi=Dialog.getCheckbox();

if (keep_roi==false){
	if (sel_meth!="From ROI Manager"){
	roiManager("reset");
}
}

if (sel_typ=="oval"){
	shape="oval";
}

//from maxima
if (sel_meth=="From Maxima"){
	run("Select None");
	run("Find Maxima...");
//waitForUser("select Maxima \n then press OK");
	getSelectionCoordinates(x1, y1);
}

//from multipoint
if (sel_meth=="From Multi-point"){
	run("Select None");
	setTool("multipoint");
waitForUser("Add points \n then press OK");
	getSelectionCoordinates(x1, y1);
	setTool("point");
}

//from ROI manager
if (sel_meth=="From ROI Manager"){
n=roiManager("count");
x1=newArray(n);
y1=newArray(n);
for (roi=0;roi<n;roi++){
	roiManager("select", roi);
	x1[roi]=getValue("X")/px;
	y1[roi]=getValue("Y")/py;
}
if (keep_roi==false){
	roiManager("reset");
	n=0;
}
}


//create ROIs
for (roi=0;roi<x1.length;roi++){
	run("Specify...", "width="+Roi_width+" height="+Roi_height+" x="+x1[roi]*px+" y="+y1[roi]*py+" "+sel_typ+" centered scaled");
	roiManager("add");
}

//rename rois
n2=roiManager("count");
for (roi=n;roi<n2;roi++){
	roiManager("select", roi);
	roiManager("rename", "ROI "+roi+1);
}

setTool("rectangle");
roiManager("Show All");	

}






//////////////////////////////////////////////////////////8

macro "Create a Single Ring ROI Action Tool - C99g H3373a1f4g6eeaf4h3e3c2b4800 C000 G3373a1f4g6eeaf4h3e3c2b4800 Cddd V7567 C000 O7567" 
{


//initialise
run("Set Measurements...", "area mean min center feret's display redirect=None decimal=3");
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
roiManager("reset");
run("Clear Results");
run("Select None");
roiManager("Show All without labels");

Dialog.create("Options");
Dialog.addCheckbox("Draw Second ROI after Drawing the First ROI", true);
Dialog.addNumber("or Enlarge/Reduce the first ROI by (+/-) "+unit, 10);
Dialog.show();

draw_outer=Dialog.getCheckbox();
enlarge_value=Dialog.getNumber();

//add first rooi
waitForUser("","Draw First ROI \n then press OK");
roiManager("add");

//add second roi
if (draw_outer==true){
	run("Select None");
waitForUser("","Draw Second ROI \n then press OK");
roiManager("add");
}else{
roiManager("select", 0);
run("Enlarge...", "enlarge=enlarge_value");
roiManager("add");
}

//create ring
roiManager("Select", newArray(0,1));
roiManager("XOR");
roiManager("Add");

//rename rois
roiManager("select", 0);
roiManager("rename", "First ROI");
roiManager("select", 1);
roiManager("rename", "Second ROI");
roiManager("select", 2);
roiManager("rename", "Ring ROI");
roiManager("Set Fill Color", "#4d00ffff");

}

/////////////////////////////////////////////////////////9

macro "Create Ring ROI's for multiple original ROI's Action Tool - C000 O1168 O3324 O8899 Oaa55 O9086 Ob242"
{

//initialise
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
n=roiManager("Count");
roiManager("Show All with labels");
Pix="";


//dialog
methods=newArray("Enlarge","Reduce","Both");
Dialog.create("Options");
	opt = newArray("Yes","No");
	if (n>0){
		Dialog.addChoice("Use the existing ROI's", opt, "Yes")
	}
Dialog.addRadioButtonGroup("Ring Createion method", methods, 3, 1, "Enlarge");
Dialog.addNumber("Enlarge by distance of "+unit, 5);
Dialog.addNumber("Reduce by distance of "+unit, 5);
Dialog.addCheckbox("Value in pixels", false);
Dialog.addCheckbox("Delete Intermediate ROI's", true);
Dialog.addCheckbox("Delete Originl ROI's after processing", false);
Dialog.show();

if (n>0){
answer=Dialog.getChoice();
if (answer=="No"){
roiManager("Reset");	
}
}
method=Dialog.getRadioButton();
enlarge_value=Dialog.getNumber();
reduce_value=Dialog.getNumber();
reduce_value=reduce_value*-1;
In_Pixels=Dialog.getCheckbox();
del_int=Dialog.getCheckbox();
del_orig=Dialog.getCheckbox();

if (In_Pixels==true){
Pix=" pixel";
}


//draw rois
waitForUser("Add ROI's", "Add ROI's to ROI Manager (Press t) \n then select OK to continue");

run("Select None");
roiManager("deselect");
n=roiManager("count");


//enlarge rois
if (method=="Enlarge"){
keep_int=2;
if (del_int==true){
	keep_int=1;	
}
oneway(enlarge_value);
}

//reduce rois
if (method=="Reduce"){
keep_int=2;
if (del_int==true){
	keep_int=1;	
}
oneway(reduce_value);
}

//both
if (method=="Both"){
	keep_int=3;
if (del_int==true){
	keep_int=1;	
}
for (roi=0;roi<n;roi++){
roiManager("select", roi)
run("Enlarge...", "enlarge=reduce_value"+Pix);
roiManager("Add");
roiManager("select", roi)
run("Enlarge...", "enlarge=enlarge_value"+Pix);
roiManager("Add");
roiManager("Select", newArray(n+(roi*keep_int),n+(roi*keep_int)+1));
roiManager("XOR");
roiManager("Add");
roiManager("deselect");
roiManager("select", n+(roi*keep_int));
roiManager("rename", "New Reduced ROI "+roi+1);
roiManager("select", n+(roi*keep_int)+1);
roiManager("rename", "New Enlarged Roi "+roi+1);
roiManager("select", n+(roi*keep_int)+2);
roiManager("rename", "Ring "+roi+1);
roiManager("deselect");
if (del_int==true){
roiManager("Select",n+(roi));
roiManager("delete");
roiManager("Select",n+(roi));
roiManager("delete");
}
}
}

if (del_orig==true){
		roiManager("deselect");
		roiManager("select", Array.getSequence(n));
		roiManager("delete");
}
else{
	for (roi=0;roi<n;roi++){
		roiManager("select", roi);
		roiManager("rename", "original ROI "+roi+1);
	}
}


function oneway(value){
for (roi=0;roi<n;roi++){
roiManager("select", roi);
roiManager("rename", "Original "+roi+1);
run("Enlarge...", "enlarge=value"+Pix);
roiManager("Add");
roiManager("Select", newArray(roi,n+(roi*keep_int)));
roiManager("XOR");
roiManager("Add");
roiManager("deselect");
roiManager("select", n+(roi*keep_int));
roiManager("rename", "New ROI "+roi+1);
roiManager("select", n+(roi*keep_int)+1);
roiManager("rename", "Ring "+roi+1);
roiManager("deselect");
if (del_int==true){
roiManager("Select",n+(roi));
roiManager("delete");
}
}
}

}







/////////////////////////////////////////////////////////10

macro "Combine & Create Ring ROI's for multiple original ROI's Action Tool - Cg00 V00dd V70d8 V67dc C0g0 V2268 V9186 V8899 C00g V4424 Vb343 Vaa55"
{

getVoxelSize(px, py, pz, unit);
n=roiManager("count");

Dialog.create("Options");
	opt = newArray("Yes","No");
	if (n>0){
		Dialog.addChoice("Use the existing ROI's", opt, "Yes")
	}
Dialog.addNumber("Enter numbr of required rings", 3);
Dialog.addNumber("Enter thickness of rings ("+unit+")", 30);
Dialog.addCheckbox("Remove Original ROI's", false);
Dialog.addCheckbox("Remove Enlarged Region ROI's", false);
Dialog.show();


if (n>0){
answer=Dialog.getChoice();
if (answer=="No"){
roiManager("Reset");	
}
}

number_of_rings=Dialog.getNumber();
increment=Dialog.getNumber();
rem_orig=Dialog.getCheckbox();
rem_Enlarged=Dialog.getCheckbox();

//draw rois
waitForUser("Add ROI's", "Add ROI's to ROI Manager (Press t) \n then select OK to continue");
run("Select None");
roiManager("deselect");
n=roiManager("count");
if (n<1){
	exit(" No ROI's");
}

//get original ROIs and combine
orig_rois=Array.getSequence(n);
roiManager("select", orig_rois);
roiManager("Combine");
roiManager("Add");


for (ring=0;ring<number_of_rings;ring++){

//create enlargements
roiManager("select", n+ring);
roiManager("rename", "Region "+ring);
run("Enlarge...", "enlarge="+increment);
roiManager("Add");
}
roiManager("select", n+ring);
roiManager("rename", "Region "+ring);


//create rings
for (ring=0;ring<number_of_rings;ring++){
roiManager("Select", newArray(n+ring,n+ring+1));
roiManager("XOR");
roiManager("Add");
}

roiManager("deselect");
roiManager("Set Fill Color", "#4d00ff00");
//label rings
for (ring=0;ring<number_of_rings;ring++){
roiManager("select", n+number_of_rings+ring+1);
roiManager("rename", "Ring "+ring+1);
}

//remove enlarged
if (rem_Enlarged==true){
for (ring=0;ring<number_of_rings;ring++){
roiManager("select", n+1);
roiManager("delete");
}
}

//remove riginal ROIs
if(rem_orig==true){
roiManager("select", orig_rois);
roiManager("delete");
}

	
}


/////////////////////////////////////////////////////////////11

macro "Create an Array of ROIs Action Tool - C000 R0044 R0744 R0e44 R7044 R7744 R7e44 Re044 Re744 Ree44" 
{

//initialise
run("Set Measurements...", "area mean min center feret's display redirect=None decimal=3");
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
roiManager("Reset");
run("Clear Results");
run("Select None");

//dialog
Dialog.create("Options");
type=newArray("rectangle","oval");
pos=newArray("top feft","centered");
Dialog.addRadioButtonGroup("Roi Type", type, 1, 2, "rectangle");
Dialog.addCheckbox("Draw Roi on Image", false);
Dialog.addMessage("or enter ROI details below");
Dialog.addNumber("Size of ROI's in X in "+unit, 10);
Dialog.addNumber("Size of ROI's in Y in "+unit, 10);
Dialog.addCheckbox("Draw spacing on image", false);
Dialog.addNumber("Spacing of ROI's in X in "+unit, 20);
Dialog.addNumber("Spacing of ROI's in Y in "+unit, 20);
Dialog.addMessage("Grid Format");
Dialog.addNumber("Number of ROI's in X", 5);
Dialog.addNumber("Number of ROI's in Y", 5);
Dialog.addRadioButtonGroup("relative position of ROI when added", pos, 1, 2, "centered");
Dialog.show();

roi_type=Dialog.getRadioButton();
roi_draw=Dialog.getCheckbox();
Roi_width=Dialog.getNumber();
Roi_width=Roi_width/py; 
Roi_height=Dialog.getNumber();
Roi_height=Roi_height/py;
get_spacing=Dialog.getCheckbox();
Spacing_width=Dialog.getNumber();
Spacing_width=Spacing_width/px;
Spacing_height=Dialog.getNumber();
Spacing_height=Spacing_height/py; 
Rois_across=Dialog.getNumber();
Rois_down=Dialog.getNumber();
Roi_pos=Dialog.getRadioButton();


//roi names
ColNum=Array.slice(Array.getSequence(Rois_across+1),1,Rois_across+1);
RowNum=Array.slice(Array.getSequence(Rois_down+1),1,Rois_down+1);


//mark first position
if (roi_draw==false){
setTool("point");
waitForUser("","Mark centre of frist ROI \n then press OK");
getSelectionBounds(X_Centre, Y_Centre, Box_width, Box_height);
}

//using draw roi
if (roi_draw==true){
setTool("rectangle");
if (roi_type=="oval"){
	setTool("oval");
}
waitForUser("","Draw frist ROI \n then press OK");
getSelectionBounds(X_Centre, Y_Centre, Box_width, Box_height);
	Roi_width=Box_width; 
	Roi_height=Box_height;
if (Roi_pos=="centered"){
	X_Centre=X_Centre+Box_width/2;
	Y_Centre=Y_Centre+Box_height/2;
} 
}


//using draw spacing
if (get_spacing==true){
	setTool("line");
waitForUser("","Draw Horizontal spacing \n then press OK");
run("Measure");
waitForUser("","Draw Vertical spacing \n then press OK");
run("Measure");
Spacing_width=getResult("Length", 0)/px;
Spacing_height=getResult("Length", 1)/py;
}



// options constrain?
Opt="";
if (roi_type=="oval"){
	Opt=Opt+" oval";
}
if (Roi_pos=="centered"){
	Opt=Opt+" centered";
}
Opt=Opt+" scaled";

setBatchMode("hide");

//main roi creation loop
roi=0;
for (Row=0;Row<Rois_down;Row++){//rows
for (Col=0;Col<Rois_across;Col++){//columns
run("Specify...", "width="+Roi_width*px+" height="+Roi_height*py+" x="+(X_Centre+Spacing_width*Col)*px+" y="+(Y_Centre+Spacing_height*Row)*py+Opt);	
roiManager("Add");
roiManager("select", roi);
roiManager("rename", "Row "+RowNum[Row]+" Col "+ColNum[Col]);
roi=roi+1;
}
}
setBatchMode("exit and display");
//finish up
selectWindow(fn);
roiManager("Show All");
}





//////////////////////////////////////////////////////////////12

macro "Distances Between a Source and Target ROI's Action Tool - C000 L44bb C00g V0057 Vbb58 T9308u Te308m "
{

//initialise
run("Set Measurements...", "area mean min centroid feret's display redirect=None decimal=2");
run("Colors...", "foreground=white background=black selection=red");

//get info
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);

Data_type=newArray(7);
n=roiManager("count");
opt=newArray("Yes","No");

//options
Dialog.create("Options");
	if (n>0){
		Dialog.addChoice("Do you want to keep existing ROI's", opt, "Yes")
	}
	Dialog.addMessage("The Source is a single ROI \nThe Target can be mutiple ROIs");
	Dialog.addMessage("Measurements to Collect \n    - (Source to Target)");
	Dialog.addCheckbox("Edge to Edge", true);
	Dialog.addCheckbox("Centre to Edge", true);
	Dialog.addCheckbox("Centre to Centre", true);
	Dialog.addCheckbox("Edge to Centre", true);
	Dialog.addMessage("Additional Measurements");
	Dialog.addCheckbox("Source Area", false);
	Dialog.addCheckbox("Target Areas", false);
	Dialog.addMessage("Other Options");
	Dialog.addCheckbox("Draw edge to edge lines", true);	
Dialog.show();

if (n>0){
answer=Dialog.getChoice();
if (answer=="No"){
roiManager("Reset");	
}
}

for (ans=0;ans<7;ans++){
	Data_type[ans]=Dialog.getCheckbox();
}


//draw Target rois
run("Remove Overlay");
setTool("freehand");
run("Select None");
roiManager("Show All");
waitForUser("Draw Multiple Target ROI's \n (press t after each one to add to Roi Manager) \n or use threshold and analyse particle to add to ROI Manager \n then press OK");
roiManager("Show All");
n=roiManager("count");


//create arrays
Target_ROI=Array.getSequence(n+1);
Target_ROI=Array.slice(Target_ROI,1);
Target_ROI_Area=newArray(n);
Target_ROI_Edge_Source_Edge=newArray(n);
Target_ROI_Centre_Source_Edge=newArray(n);
Target_ROI_Edge_Source_Centre=newArray(n);
Target_ROI_Centre_Source_Centre=newArray(n);
X1=newArray(n);
Y1=newArray(n);
X2=newArray(n);
Y2=newArray(n);

//Target rename and add centres
for (roi=0;roi<n;roi++){
	roiManager("select", roi);
	roiManager("rename", "Target ROI "+roi+1);
	Target_ROI_Area[roi]=getValue("Area");
if (Data_type[2]==1 || Data_type[3]==1){
//	Target_ROI_Area[roi]=getValue("Area");
	c_x=getValue("XM")/px;
	c_y=getValue("YM")/py;
	makeOval(c_x, c_y, 1, 1);
	roiManager("add");
	roiManager("select", roi+n);
	roiManager("rename", "Target ROI Centre_M "+roi-n+1);
}
}



n_data=roiManager("count");

//add Source roi
roiManager("Show All");
setTool("freehand");
waitForUser("Draw Single Source ROI then press t to add to Roi Manager \n or use threshold and analyse particles to add to Roi Manager\n then press OK");
//roiManager("add");
roiManager("select", n_data);
roiManager("rename", "Source ROI");
Source_Area=getValue("Area");

//Source centre
if (Data_type[1]==1 || Data_type[2]==1){
c_x=getValue("XM")/px;
c_y=getValue("YM")/py;
makeOval(c_x, c_y, 1, 1);
roiManager("add");
roiManager("select", n_data+1);
	roiManager("rename", "Source centre M");
run("Select None");
}

setBatchMode("hide");
run("Text Window...", "name=[Process] width=20 height=1");
print("[Process]", "Processing\n");

//create EDT for Target edge and measure
newImage("mask", "8-bit black", ImageWidth, ImageHeight, 1);
setVoxelSize(px, py, pz, unit);
roiManager("select", n_data);
roiManager("fill");
setAutoThreshold("Default dark");
setOption("BlackBackground", false);
run("Convert to Mask");
run("Invert");
run("Exact Signed Euclidean Distance Transform (3D)");
selectWindow("mask");
close();
//get data
selectWindow("EDT");
for (roi=0;roi<n;roi++){
roiManager("select", roi);	
Target_ROI_Edge_Source_Edge[roi]=getValue("Min")*px;
//////create x1y1
Roi.getContainedPoints(xpoints, ypoints);
int=newArray(xpoints.length);
for (pt=0;pt<xpoints.length;pt++){
int[pt]=getPixel(xpoints[pt], ypoints[pt]);	
}
loc=Array.rankPositions(int);
X1[roi]=xpoints[loc[0]];
Y1[roi]=ypoints[loc[0]];
///////////////
if (Data_type[3]==1){
roiManager("select", roi+n);
Target_ROI_Centre_Source_Edge[roi]=getValue("Min")*px;
}
}
close();


//create EDT for Source centre and measure
if (Data_type[1]==1 || Data_type[2]==1){
newImage("mask", "8-bit black", ImageWidth, ImageHeight, 1);
setVoxelSize(px, py, pz, unit);
roiManager("select", n_data+1);
roiManager("fill");
setAutoThreshold("Default dark");
setOption("BlackBackground", false);
run("Convert to Mask");
run("Invert");
run("Exact Signed Euclidean Distance Transform (3D)");
selectWindow("mask");
close();
//get data
selectWindow("EDT");
for (roi=0;roi<n;roi++){
if (Data_type[1]==1){	
roiManager("select", roi);	
Target_ROI_Edge_Source_Centre[roi]=getValue("Min")*px;
}
if (Data_type[2]==1){
roiManager("select", roi+n);
Target_ROI_Centre_Source_Centre[roi]=getValue("Min")*px;
}
}
close();
}

//////create x2y2
for (roi=0;roi<n;roi++){
newImage("mask", "8-bit black", ImageWidth, ImageHeight, 1);
setVoxelSize(px, py, pz, unit);
roiManager("Select", roi);
roiManager("fill");
setAutoThreshold("Default");
setOption("BlackBackground", false);
run("Convert to Mask");
run("Exact Signed Euclidean Distance Transform (3D)");
roiManager("Select", n_data);
Roi.getContainedPoints(xpoints, ypoints);
int=newArray(xpoints.length);
for (pt=0;pt<xpoints.length;pt++){
int[pt]=getPixel(xpoints[pt], ypoints[pt]);	
}
loc=Array.rankPositions(int);
X2[roi]=xpoints[loc[0]];
Y2[roi]=ypoints[loc[0]];
close();
close();
}
///////


//draw lines
if (Data_type[6]==1){
new_n=roiManager("count");
for (roi=0;roi<n;roi++){
makeLine(X1[roi], Y1[roi], X2[roi], Y2[roi]);
roiManager("add");
roiManager("select", new_n+roi);
roiManager("rename", "line "+roi+1);
}
}

selectWindow("Process");
run("Close");
setBatchMode("exit and display");


//table of results
Table.create(fn+" Results");
Table.setLocationAndSize(200, 200, 800, 200)
Table.setColumn("Target ROI", Target_ROI);
if (Data_type[5]==1){
Table.setColumn("Target ROI Aea", Target_ROI_Area);
}
if (Data_type[0]==1){
Table.setColumn("Source Edge to Target Edge ("+unit+")", Target_ROI_Edge_Source_Edge);
}
if (Data_type[2]==1){
Table.setColumn("Source Centre to Target Centre ("+unit+")", Target_ROI_Centre_Source_Centre);
}
if (Data_type[1]==1){
Table.setColumn(" Source Centre to Target Edge ("+unit+")", Target_ROI_Edge_Source_Centre);
}
if (Data_type[3]==1){
Table.setColumn("Source Edge to Target Centre ("+unit+")", Target_ROI_Centre_Source_Edge);
}
if (Data_type[4]==1){
	Table.set("Source ROI Aea", 0, Source_Area);
}


//finish up
selectWindow(fn);
run("Remove Overlay");
roiManager("Show All with labels");

}

//////////////////////////////////////13


macro "Distances Between a Source and Target ROI's Multi Channel Action Tool - C00g V0833 V0034 Vca33 V6f34 Cg00 Vbf33 Vd534 V1d33 V5834 C000 T9308u Te308m"
{

run("Set Measurements...", "area mean min centroid display redirect=None decimal=2");
run("Clear Results");

//get info
fn=getTitle();
getVoxelSize(px, py, pz, unit);
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
roiManager("reset");


if (ImageChannels<2){
	exit("This macro requires an image with at least 2 channels");
}
//get number of channels
chs=newArray(ImageChannels);
for (ch=0;ch<ImageChannels;ch++){
	chs[ch]="Channel "+ch+1;
}

//dialog
Dialog.create("Options");
Dialog.addMessage("This macro will measure disatnces from each Target ROI \n to the nearest object in the Source ROI");
Dialog.addMessage("If necessary, run any filtering and background subtraction \n before running this macro");
Dialog.addMessage("Source Channel (S)");
Dialog.addMessage("- single ROI object/s");
Dialog.addChoice("Source Channel)", chs, chs[0]);
Dialog.addMessage("Target Channel (T)");
Dialog.addMessage(" - mutliple ROI's ");
Dialog.addChoice("Target Channel", chs, chs[1]);
Dialog.addCheckbox("Keep EDT images", false);
Dialog.addMessage("NB. negative values give distances inside edges");
Dialog.show();

Source=Dialog.getChoice();
Target=Dialog.getChoice();
EDT_keep=Dialog.getCheckbox();

//error check
if (Source==Target){
	exit("Source and target cannot be the same image "); 
}

Source=Source.substring(Source.length-1);
Target=Target.substring(Target.length-1);


//create Target ROIs
selectWindow(fn);
run("Select None");
run("Duplicate...", "title=Target duplicate channels="+Target+"");
setAutoThreshold("Default dark");
waitForUser("Adjust Threshold for Target ROI's \n then press ok \n -------------------- \n NB - set detection criteria in the next window  \n and select the 'Add to Manager' \n ---------------------");
run("Analyze Particles...");
selectWindow("Target");
close();

n=roiManager("count");
if (n<1){
	exit("No ROI's detected or adders to ROI manager");
}


//create Source image edges
run("Select None");
run("Duplicate...", "title=[mask edges] duplicate channels="+Source+"");
run("Threshold...");
setAutoThreshold("Default dark");
waitForUser("Adjust Threshold for Source Map \n then press ok");
setOption("BlackBackground", false);
run("Convert to Mask");

//create Source image centres
selectWindow("mask edges");
run("Duplicate...", "title=[mask centres]");
selectWindow("mask centres");
run("Ultimate Points"); 
setThreshold(1, 255);
run("Convert to Mask");

//create EDT image centres and measure
selectWindow("mask centres");
run("Invert");
run("Exact Signed Euclidean Distance Transform (3D)");
roiManager("measure");
Table.applyMacro("Centre_Edge=Min*"+px+"", "Results");
Table.applyMacro("Centre_Centre=Mean*"+px+"", "Results");
selectWindow("EDT");
rename("EDT Centres");
selectWindow("mask centres");
close();
Centre_Edge=Table.getColumn("Centre_Edge");
Centre_Centre=Table.getColumn("Centre_Centre");
run("Clear Results");

//create EDT image edges and measure
selectWindow("mask edges");
run("Invert");
run("Exact Signed Euclidean Distance Transform (3D)");
roiManager("measure");
Table.applyMacro("Edge_Edge=Min*"+px+"", "Results");
Table.applyMacro("Edge_Centre=Mean*"+px+"", "Results");
selectWindow("EDT");
rename("EDT Edges");
selectWindow("mask edges");
close();
Edge_Edge=Table.getColumn("Edge_Edge");
Edge_Centre=Table.getColumn("Edge_Centre");
selectWindow("Results");
run("Close");

//keep EDT option
if (EDT_keep==false){
selectWindow("EDT Edges");
close();
selectWindow("EDT Centres");
close();
}

//create table of results
Table.create(fn+" Data");
Table.setLocationAndSize(200, 299, 800, 600);
Table.showRowNumbers(true);
Table.setColumn("Centre(S) to Centre(T) "+unit, Centre_Centre);
Table.setColumn("Centre(S) to Edge(T) "+unit, Centre_Edge);
Table.setColumn("Edge(S) to Centre(T) "+unit, Edge_Centre);
Table.setColumn("Edge(S) to Edge(T) "+unit, Edge_Edge);
}



////////////////////////////////////////14

macro "Distances between 2 Nested ROI's Action Tool - C000 L4478 C00g O04fe O6956 T9308u Te308m "
{

//initialise
run("Set Measurements...", "area mean min centroid feret's display redirect=None decimal=2");
run("Colors...", "foreground=white background=black selection=white");


//get info
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);

//arrays
title=newArray("Minimum Distance ("+unit+")","Maximum Distance ("+unit+")","Space Area (Sq "+unit+")");
data=newArray(3);
X1=newArray(2);
Y1=newArray(2);
X2=newArray(2);
Y2=newArray(2);

run("Remove Overlay");
roiManager("reset");
setTool("freehand");
run("Select None");
roiManager("Show None");

//draw rois and create ring roi
waitForUser("Draw Inner ROI \n then press OK");
roiManager("add");
roiManager("Show All");
waitForUser("Draw Outer ROI \n then press OK");
roiManager("add");
roiManager("Select", newArray(0,1));
roiManager("XOR");
roiManager("Add");
roiManager("deselect");


setBatchMode("hide");
run("Text Window...", "name=[Process] width=20 height=1");
print("[Process]", "Processing\n");

//create EDT for max distance
newImage("mask", "8-bit black", ImageWidth, ImageHeight, 1);
setVoxelSize(px, py, pz, unit);
roiManager("select", 0);
roiManager("fill");
run("Invert");
run("Exact Signed Euclidean Distance Transform (3D)");
roiManager("select", 1);
longest=getValue("Max")*px;
//get xy
Roi.getContainedPoints(xpoints, ypoints);
int=newArray(xpoints.length);
for (pt=0;pt<xpoints.length;pt++){
int[pt]=getPixel(xpoints[pt], ypoints[pt]);	
}
loc=Array.rankPositions(int);
loc=Array.reverse(loc);
X2[1]=xpoints[loc[0]];
Y2[1]=ypoints[loc[0]];
makeOval(X2[1], Y2[1],1,1);
roiManager("add");
/////
selectWindow("mask");
close();
selectWindow("EDT");
close();


//get inner point for max
newImage("mask", "8-bit black", ImageWidth, ImageHeight, 1);
setVoxelSize(px, py, pz, unit);
roiManager("select", 3);
roiManager("fill");
run("Exact Signed Euclidean Distance Transform (3D)");
roiManager("select", 0);
Roi.getContainedPoints(xpoints, ypoints);
int=newArray(xpoints.length);
for (pt=0;pt<xpoints.length;pt++){
int[pt]=getPixel(xpoints[pt], ypoints[pt]);	
}
loc=Array.rankPositions(int);
loc=Array.reverse(loc);
X1[1]=xpoints[loc[0]];
Y1[1]=ypoints[loc[0]];
makeOval(X1[1], Y1[1],1,1);
roiManager("add");
selectWindow("mask");
close();
selectWindow("EDT");
close();


//create EDT for min distance
newImage("mask", "8-bit black", ImageWidth, ImageHeight, 1);
setVoxelSize(px, py, pz, unit);
roiManager("select", 1);
roiManager("fill");
run("Exact Signed Euclidean Distance Transform (3D)");
roiManager("select", 0);
shortest=getValue("Min")*px;
//get xy
Roi.getContainedPoints(xpoints, ypoints);
int=newArray(xpoints.length);
for (pt=0;pt<xpoints.length;pt++){
int[pt]=getPixel(xpoints[pt], ypoints[pt]);	
}
loc=Array.rankPositions(int);
X1[0]=xpoints[loc[0]];
Y1[0]=ypoints[loc[0]];
makeOval(X1[0], Y1[0],1,1);
roiManager("add");
/////
selectWindow("mask");
close();
selectWindow("EDT");
close();


//get outer point for min
newImage("mask", "8-bit black", ImageWidth, ImageHeight, 1);
setVoxelSize(px, py, pz, unit);
roiManager("select", 5);
roiManager("fill");
run("Exact Signed Euclidean Distance Transform (3D)");
roiManager("select", 1);
run("Make Inverse");
roiManager("update");
roiManager("select", 1);
Roi.getContainedPoints(xpoints, ypoints);
int=newArray(xpoints.length);
for (pt=0;pt<xpoints.length;pt++){
int[pt]=getPixel(xpoints[pt], ypoints[pt]);	
}
loc=Array.rankPositions(int);
loc=Array.reverse(loc);
X2[0]=xpoints[loc[0]];
Y2[0]=ypoints[loc[0]];
makeOval(X2[0], Y2[0],1,1);
roiManager("add");
selectWindow("mask");
close();
selectWindow("EDT");
close();
roiManager("select", 1);
run("Make Inverse");
roiManager("update");


//measures
data[0]=shortest;
data[1]=longest;
roiManager("select", 2);
data[2]=getValue("Area");

//rename rois
roi_name=newArray("Inner ROI","Outer ROI","Ring ROI","Max Outer","Max Inner","Min Inner","Min Outer","Shortest","Longest" );
for (roi=0;roi<2;roi++){
makeLine(X1[roi], Y1[roi], X2[roi], Y2[roi]);
roiManager("add");
}
for (roi=0;roi<9;roi++){
roiManager("select", roi);
roiManager("rename", roi_name[roi]);
}

selectWindow("Process");
run("Close");
setBatchMode("exit and display");


//result table
Table.create(fn+" data");
Table.setLocationAndSize(400, 200, 400, 200);
Table.setColumn("Measurement", title);
Table.setColumn("value", data);

selectWindow(fn);
roiManager("Show All");

}


//////////////////////////////////////15

macro "Distances Between Source and Target ROI's 3D Action Tool - C000 L44bb C00g V0057 Vbb58 T9308u Te308m C000 T0h083 T4h08D"
{

//initialise
run("3D OC Options", "volume nb_of_obj._voxels centroid dots_size=5 font_size=10 redirect_to=none");
run("Set Measurements...", "area mean min centroid display redirect=None decimal=3");
run("Colors...", "foreground=white background=black selection=green");
roiManager("reset");
run("Clear Results");
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);

if (ImageChannels<2){
	exit("This macro requires an image with at least 2 channels");
}


//get number of channels
chs=newArray(ImageChannels);
for (ch=0;ch<ImageChannels;ch++){
	chs[ch]="Channel "+ch+1;
}

//dialog
Dialog.create("Options");
Dialog.addMessage("Source Channel");
Dialog.addMessage("- single ROI object/s \n - distances are measured from the edge of this object \n - negative values give distances inside edge");
Dialog.addChoice("Source Channel)", chs, chs[0]);
Dialog.addMessage("Target Channel");
Dialog.addMessage(" - mutliple ROI's \n - distances are from the centre of these ROI's");
Dialog.addChoice("Target Channel", chs, chs[1]);
Dialog.addMessage("If necessary, run any filtering and background subtraction \n before running this macro");
Dialog.addMessage("Measurement Type");
Dialog.addCheckbox("Measure Source Edge to Target Centre", true);
Dialog.addCheckbox("Measure Source Centre to Target Centre", true);
Dialog.show();

Source=Dialog.getChoice();
Target=Dialog.getChoice();
meas_edge=Dialog.getCheckbox();
meas_centre=Dialog.getCheckbox();

if (meas_edge==false && meas_centre==false){
	exit("No measurement type selected")
}

//error check
if (Source==Target){
	exit("Source and target cannot be the same image "); 
}



////////////create EDT roi source //////////////
ch=Source.substring(Source.length-1);

//edge method
if (meas_edge==true){
selectWindow(fn);
run("Select None");
run("Duplicate...", "title=[Source_mask] duplicate channels=ch");
run("Threshold...");
waitForUser("Select Threshold \n then press OK");
run("Convert to Mask", "background=Dark");
run("Invert", "stack");
run("Exact Signed Euclidean Distance Transform (3D)");
selectWindow("Source_mask");
close();
selectWindow("EDT");
rename("Edge EDT");
}

//centre method
if (meas_centre==true){
selectWindow(fn);
run("Select None");
run("Duplicate...", "title=[Source_mask] duplicate channels=ch");
run("3D Objects Counter");
//extract centres
Xpos_source=Table.getColumn("X");
Ypos_source=Table.getColumn("Y");
Zpos_source=Table.getColumn("Z");
selectWindow("Results");
run("Close");
selectWindow("Source_mask");
close();
for (roi=0;roi<Xpos_source.length;roi++){
newImage("New_Mask", "8-bit black", ImageWidth, ImageHeight, 1, ImageSlices ,1);
run("Specify...", "width=1 height=1 x="+Xpos_source[roi]+" y="+Ypos_source[roi]+" slice="+round(Zpos_source[roi])+" oval");
run("Draw", "slice");
run("Select None");
run("Invert", "stack");
run("Exact Signed Euclidean Distance Transform (3D)");
selectWindow("New_Mask");
close();
}
selectWindow("EDT");
rename("Centre EDT");
}


/////////////find target roi centres///////////////
selectWindow(fn);
run("Select None");
ch=Target.substring(Target.length-1);
run("Duplicate...", "title=[Target_mask] duplicate channels=ch");
run("3D Objects Counter");
selectWindow("Target_mask");
close();

//extract centres
Xpos=Table.getColumn("X");
Ypos=Table.getColumn("Y");
Zpos=Table.getColumn("Z");
selectWindow("Results");
run("Close");


/////////create roi centres on slices/////////
roi_num=newArray(Xpos.length);	
for (roi=0;roi<Xpos.length;roi++){
run("Specify...", "width=1 height=1 x="+Xpos[roi]+" y="+Ypos[roi]+" slice="+round(Zpos[roi])+" oval");
roiManager("add");
roi_num[roi]=roi+1;
}


/////////get distances///////////
if (meas_edge==true){
selectWindow("Edge EDT");
setVoxelSize(px, py, pz, unit);
sub_dist_edge=SubDist();
dist_edge=SliceMeasure();
}

if (meas_centre==true){
selectWindow("Centre EDT");
setVoxelSize(px, py, pz, unit);
sub_dist_centre=SubDist();
dist_centre=SliceMeasure();
}


//create table of results
Table.create("Distances");
Table.setLocationAndSize(700, 200, 600, 600);
Table.setColumn("Particle", roi_num);
Table.setColumn("X", Xpos);
Table.setColumn("Y", Ypos);
Table.setColumn("Z", Zpos);
if (meas_edge==true){
Table.setColumn("Edge-Centre (slice) "+unit, dist_edge);
Table.setColumn("Edge-Centre (sub-slice) "+unit, sub_dist_edge);
}
if (meas_centre==true){
Table.setColumn("Centre-Centre (slice) "+unit, dist_centre);
Table.setColumn("Centre-Centre (sub-slice) "+unit, sub_dist_centre);
}



/////sub distance measure
function SubDist() {
	sub=newArray(Xpos.length); 
for (roi=0;roi<Xpos.length;roi++){
if (Zpos[roi]!=floor(Zpos[roi])){
run("Specify...", "width=1 height=1 x="+Xpos[roi]+" y="+Ypos[roi]+" slice="+floor(Zpos[roi])+" oval");
low=getValue("Min");
run("Specify...", "width=1 height=1 x="+Xpos[roi]+" y="+Ypos[roi]+" slice="+floor(Zpos[roi]+1)+" oval");
high=getValue("Min");
frac=floor(Zpos[roi])-Zpos[roi];
sub[roi]=(low+(low-high)*frac)*px;
}else{
	run("Specify...", "width=1 height=1 x="+Xpos[roi]+" y="+Ypos[roi]+" slice="+Zpos[roi]+" oval");
sub[roi]=getValue("Min")*px;
}
}
return sub;
}


///slice measure
function SliceMeasure() { 
roiManager("measure");
//read min data
dist=Table.getColumn("Min");
for (roi=0;roi<Xpos.length;roi++){
dist[roi]=dist[roi]*px;
}
selectWindow("Results");
run("Close");
return dist;
}

}

///////////////////////////////////////15
