//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 "Image Information Summary Action Tool - Cbbg V00ff C00g O00ff  T7e14i T8e14i T7d14i T8d14i" 
{
//get info
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
Stack.getUnits(X, Y, Z, Time, value);
getVoxelSize(px,py,pz,unit);

//for timee series
if (ImageFrames>1){
frInt=Stack.getFrameInterval();
ft=Time;
fr=frInt;
if (fr>1 && ft=="sec"){
	fr=fr/60;
	ft="min";
}	
if (fr>1 && ft=="min"){
	fr=fr/60;
	ft="Hr";	
}
frRate=round(1/fr);
dur=ImageFrames/frRate;
}

//Bit depth
bd1=bitDepth();
bd=bd1;
if (bd1==24){
	bd=8;
}


setBatchMode(true);
///////////////////////graphs/////////////////////////


//for multichannel and or multislice
if (ImageChannels>1){	
for (Ch=1;Ch<=ImageChannels;Ch++){
	selectWindow(fn);
	run("Duplicate...", "title=int duplicate channels="+Ch);
	selectWindow("int");
	col=lookup();
	if (ImageSlices>1 || ImageFrames>1){
	Stack.getStatistics(voxelCount, mean, min, max, stdDev);
	getRawStatistics(area1, mean1, min1, max1, std1, histogram);
	}
	else{
	getRawStatistics(area, mean, min, max, std, histogram);	
	}	
close();
Plot_Histogram();
}
//stack histograms
run("Images to Stack", "name=Histogram title=Histogram");
run("Make Montage...", "columns=1 rows="+ImageChannels+" scale=1 border=2");
selectWindow("Histogram");
close();
selectWindow("Montage");
rename("Graphs");
getDimensions(gWidth, gHeight, gChannels, gSlices, gFrames);
}


//single channel and or mutlislice
else{
		if (ImageSlices>1 || ImageFrames>1){
	Stack.getStatistics(voxelCount, mean, min, max, stdDev);  
	getRawStatistics(area1, mean1, min1, max1, std1, histogram);
	}
	else{
	getRawStatistics(npix, mean, min, max, std, histogram);	
	}
Ch="1";
col="Red";
Plot_Histogram();
rename("Graphs");
getDimensions(gWidth, gHeight, gChannels, gSlices, gFrames);	
}



////////////////////////////////images////////////////


if (ImageChannels>1){
for (Ch=1;Ch<=ImageChannels;Ch++){
selectWindow(fn);
run("Duplicate...", "title=Dup duplicate channels="+Ch);
Image_Process();
rename("Chan "+Ch);
}


//stack Images
run("Images to Stack", "name=Images title=Chan");
run("Make Montage...", "columns=1 rows="+ImageChannels+" scale=.5 border=2");
selectWindow("Images");
close();

}
//for single channel
else{
	selectWindow(fn);
	run("Duplicate...", "title=Dup duplicate");
Image_Process();	
}


//////////////scale and join//////////
selectWindow("Montage");
run("RGB Color");
rename("Thumbnail");
getDimensions(ImWidth, ImHeight, ImChannels, ImSlices, ImFrames);
sc=gHeight/ImHeight;
run("Scale...", "x="+sc+" y="+sc+" width="+ImWidth*sc+" height="+ImHeight*sc+" interpolation=Bilinear average create");
rename("Images");
run("Combine...", "stack1=Graphs stack2=Images");
rename(fn+" Summary");
selectWindow("Thumbnail");
close();
selectWindow(fn+" Summary");
setBatchMode("show");


///////////////end/////////

function Image_Process(){
//for Z and Time
if (ImageSlices>1 && ImageFrames>1){
run("Z Project...", "projection=[Max Intensity] all");
selectWindow("Dup");
close();
selectWindow("MAX_Dup");
rename("Dup");
}

//for z or time
if (ImageSlices>1 || ImageFrames>1){
selectWindow("Dup");
run("Z Project...", "projection=[Max Intensity]");
selectWindow("Dup");
close();
selectWindow("MAX_Dup");
}
rename("Montage");
if (bd1!=24){

setMinAndMax(0, pow(2,bd));
run("HiLo");
}
}


function Plot_Histogram(){
//plot routine
	Array.getStatistics(histogram, Gmin, Gmax, Gmean, GstdDev);
	Plot.create("Histogram Channel "+Ch, "Intensity", "Count");
		Plot.setLineWidth(2);
//		Plot.setColor(col,"#ddddff");
		Plot.setColor(col,col);		
		Plot.add("bars", histogram);
		Plot.setColor("Black"); 
		Plot.addText("Px="+px+" "+unit, 0.15, 0.1);
		Plot.addText("Py="+py+" "+unit, 0.15, 0.2);
		Plot.addText("Pz="+pz+" "+unit, 0.15, 0.3);
		Plot.addText("Frames="+ImageFrames, 0.15, 0.4);
		Plot.addText("Size X="+ImageWidth, 0.5, 0.1);
		Plot.addText("Size Y="+ImageHeight, 0.5, 0.2);
		Plot.addText("Z slices="+ImageSlices, 0.5, 0.3);
		Plot.addText("Channel "+Ch, 0.8, 0.1);
		Plot.addText("Min="+min, 0.8, 0.2);
		Plot.addText("Max="+max, 0.8, 0.3);
		Plot.addText("Bit Depth="+bd1, 0.8, 0.4);
		Plot.setLimits(0, pow(2,bd),0, Gmax+Gmax*0.05);
if (ImageFrames>1){
		Plot.addText(frRate+" frames / "+ft, 0.15, 0.5); 
		Plot.addText("Interval="+frInt+" "+Time, 0.5, 0.4);
		Plot.addText("duration="+dur+" "+ft, 0.5, 0.5);
}	
	Plot.show();
}	


function lookup(){
getLut(reds, greens, blues);
Array.getStatistics(reds, min, max, mean, stdDev);
re=max;
RED=toHex(re);
if (re<17){
RED=RED+"0";	
}
Array.getStatistics(greens, min, max, mean, stdDev);
gr=max;
GREEN=toHex(gr);
if (gr<17){
GREEN=GREEN+"0";	
}
Array.getStatistics(blues, min, max, mean, stdDev);
bl=max;
BLUE=toHex(bl);
if (bl<17){
BLUE=BLUE+"0";	
}
col="#"+RED+GREEN+BLUE;
if (col=="#ffffff"){
col="Black";
}
return col;
}

}



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

macro "Live Image Ruler image Action Tool - C000 T0508L T6508i T8508v Te508e T1h08r T5h08u Tah08l Tch08e Thh08r Cg00 L08g8 L0709 Lg7g9" 
{

//initialise
run("Set Measurements...", "area mean min centroid area_fraction display redirect=None decimal=3");

//arays
tl=newArray("line","arrow");
cols=newArray("White","Black","Red","Green","Blue","Magenta","Cyan","Yellow");
arr=newArray("Notched","Filled","Open","Bar");

//options
Dialog.create("Options");
	Dialog.addChoice("Ruler tool", tl);
	Dialog.addChoice("Line & text Colour", cols);
	Dialog.addMessage("Arrow Options");
	Dialog.addChoice("Line Colour", arr);
Dialog.show();	

settl=Dialog.getChoice();
lncol=Dialog.getChoice();
arropt=Dialog.getChoice();

//set defaults
run("Colors...", "foreground=white background=black selection="+lncol);
setColor(lncol);

//exit window
run("Text Window...", "name=[Live Line Measurements] width=65 height=3 monospaced");
print("[Live Line Measurements]", "\\Update: \n Close This Window to Exit Live line Measure");
setLocation(0, 0);


//main routine
do {
//get image info
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
zm=getZoom();
getVoxelSize(px, py, pz, unit);

// tool measure
if (settl=="line"){
setTool("line");
//run("Line Width...", "line="+ImageHeight/(250*zm));
} else if (settl=="arrow"){
setTool("arrow");
run("Arrow Tool...", "width=1 size=4 color="+lncol+" style="+arropt+" double");
//run("Arrow Tool...", "width="+ImageHeight/(250*zm)+" size=4 color="+lncol+" style="+arropt+" double");
}

//pause
wait(150);

//get length
run("Measure");
if (nResults>0){
ln=getResult("Length", 0);
x=getResult("X", 0)/px;
y=getResult("Y", 0)/px;
an=getResult("Angle", 0);
if (an>90 || an<-90){
	an=an-180;
}

//display length
l=toString(ln)+" "+unit;
Overlay.remove;
setFont("SansSerif", 25/zm, "antialiased");
Overlay.drawString(l, x, y,an);
Overlay.show();
run("Clear Results");
}

//exit option
a=isOpen("Live Line Measurements");

} while(a==1);


//tidy up
Overlay.remove;
setTool("line");
}








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

macro "Add text with symbols Action Tool - C000 O42ac O538a L3fff L3efe Ceee L8a8h L9a9h" 
{

run("Colors...", "foreground=white background=black selection=white");
setTool("point");
SymbolCode=newArray("Add Text",fromCharCode(945),fromCharCode(946),fromCharCode(947),fromCharCode(948),fromCharCode(949),
fromCharCode(950),fromCharCode(951),fromCharCode(952),fromCharCode(953),fromCharCode(954),fromCharCode(955),fromCharCode(956),
fromCharCode(957),fromCharCode(958),fromCharCode(959),fromCharCode(960),fromCharCode(963),fromCharCode(969),fromCharCode(916),
fromCharCode(931),fromCharCode(937),fromCharCode(176), fromCharCode(8734), fromCharCode(8800),fromCharCode(8804),fromCharCode(8805),
fromCharCode(189), fromCharCode(188), fromCharCode(10026), fromCharCode(10032),fromCharCode(10038),fromCharCode(10036),fromCharCode(187),
fromCharCode(171),fromCharCode(8730),fromCharCode(169),fromCharCode(10132),fromCharCode(10145));
TextSymb="";
cols=newArray("White","Black","Red","Green","Blue","Magenta","Cyan","Yellow");
styles=newArray("Plain","Bold","Italic","bold+Italic");
fonts=newArray("SansSerif","Serif","Arial");


do {
Dialog.create("Options");
Dialog.addMessage("This window loops to allow adding of both standard text to the 'Current Text' box or adding symbols.") 
Dialog.addMessage("The Current text box updates after each click of OK."); 
Dialog.addMessage("When finished adding text, Check the print text box to finish and print on the image");
Dialog.addMessage("The text is added to the ROI manager allowing repositioning and editing. \n \n Finally, when finished editing, flatten the image using the ROI manager");
Dialog.addRadioButtonGroup("Create Text", SymbolCode, 4, 10, SymbolCode[0]);
Dialog.addString("Current Text", TextSymb, 50);
Dialog.addCheckbox("Print text on Image", false);
Dialog.addMessage("Format options");
Dialog.addChoice("Font", fonts)
Dialog.addToSameRow();
Dialog.addChoice("Style", styles)
Dialog.addToSameRow();
Dialog.addNumber("Size", 36);
Dialog.addToSameRow();
Dialog.addChoice("Colour", cols);
Dialog.show();

option=Dialog.getRadioButton();
add_text=Dialog.getString();
end=Dialog.getCheckbox();
font_size=Dialog.getNumber();
font_type=Dialog.getChoice();
font_style=Dialog.getChoice();
font_colour=Dialog.getChoice();

 if (option=="Add Text"){
		TextSymb=add_text;
}
 else {
	TextSymb=TextSymb+option;
}

} while (end==false);


setFont(font_type, font_size, font_style);

waitForUser("", "mark position for text");
getSelectionBounds(x, y, width, height);
makeText(TextSymb, x, y);

Roi.setStrokeColor(font_colour);
roiManager("Add");
roiManager("Show All");
run("Select None");

setTool("rectangle");
}









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

macro "Set LUT to wavelength colour Action Tool - C66g T1708L F0d33 C0dd F3d33 T7708U C0g0  F6d33 Cgg0 F9d33 Cg00 Te708T Fcd33 Cd08 Ffd33 "
{

if (bitDepth()==24){
	exit("This macro does not work on RGB images"); 
}

wavelength=newArray(350, 355, 360, 365, 370, 375, 380, 385, 390, 395, 400, 405, 410, 415, 420, 425, 430, 435, 440, 445, 
450, 455, 460, 465, 470, 475, 480, 485, 490, 495, 500, 505, 510, 515, 520, 525, 530, 535, 540, 545, 
550, 555, 560, 565, 570, 575, 580, 585, 590, 595, 600, 605, 610, 615, 620, 625, 630, 635, 640, 645, 
650, 655, 660, 665, 670, 675, 680, 685, 690, 695, 700, 705, 710, 715, 720, 725, 730, 735, 740, 745, 
750, 755, 760, 765, 770, 775, 780, 785, 790, 795, 800); 
SpectrumRed=newArray(148, 148, 148, 148, 148, 148, 148, 160, 168, 172, 175, 174, 171, 165, 155, 153, 113, 83, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 106, 127, 145, 160, 174, 186, 
198, 209, 219, 228, 237, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 249, 244, 239, 233, 228, 222, 216, 210, 203, 
196, 189, 182, 174, 166, 157, 148, 148, 148, 148, 148); 
SpectrumGreen=newArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 
123, 148, 168, 186, 202, 217, 230, 242, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
255, 255, 255, 255, 255, 255, 255, 255, 236, 226, 216, 204, 193, 180, 165, 150, 131, 109, 80, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); 
SpectrumBlue=newArray(148, 148, 148, 148, 148, 148, 148, 166, 182, 196, 210, 222, 233, 244, 255, 255, 255, 255, 255, 255, 
255, 255, 255, 255, 255, 255, 255, 255, 255, 224, 186, 136, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); 


wl=getNumber("Input wavelength (350-800nm)", 525);

if (wl<350){
	wl=350;
}
if (wl>800){
	wl=800;
}

ref=(wl-350)/5;

redmax=SpectrumRed[ref];
greenmax=SpectrumGreen[ref];
bluemax=SpectrumBlue[ref];

red=newArray(256);
green=newArray(256);
blue=newArray(256);

for (i=0;i<256;i++){
	red[i]=floor(i*(redmax+1)/256);
	green[i]=floor(i*(greenmax+1)/256);
	blue[i]=floor(i*(bluemax+1)/256);
}

setLut(red, green, blue);
}


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

macro "Create and save a Lookup Table from an RGB Image Action Tool - C66g T1g08L C0dd  T7g08U  Cg00 Teg08T C000 T0708M T6708a Tb708k Tg708e" 
{
setTool("point");
waitForUser("Select","Click on colour on RGB image then click OK to continue");
if (bitDepth()!=24){
	exit("This is not an RGB image"); 
}
getSelectionCoordinates(x, y);
pxValue=getPixel(x[0],y[0]);
       redmax=(pxValue>>16)&0xff;  // extract red byte (bits 23-17)
       greenmax=(pxValue>>8)&0xff; // extract green byte (bits 15-8)
       bluemax=pxValue&0xff;       // extract blue byte (bits 7-0)

red=newArray(256);
green=newArray(256);
blue=newArray(256);


for (i=0;i<256;i++){
	red[i]=floor(i*(redmax+1)/256);
	green[i]=floor(i*(greenmax+1)/256);
	blue[i]=floor(i*(bluemax+1)/256);
}

//Array.show(red,green,blue);
newImage("LutImage", "8-bit white", 16, 16, 1);
setLut(red, green, blue);


name=getString("LUT name ","NewLut");
lutDir=getDirectory("luts");
saveAs("lut",lutDir+name);
setTool("rectangle");
selectWindow("LutImage");
close();
}



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

macro "Invert Intensities Action Tool - Cccc F00h9 C000 T0708I T4708N Ta708V C000 F09ha Cggg  T1h08I T6h08N  Tdh08T" 
{

//invert intensities

BD=bitDepth();

if (BD==24){
	BD=8;
}

if (BD==32){
	exit("Image is 32-Bit - use Reciprocal command");
}
a=pow(2, BD);


level="code=v="+a-1+"-v stack";

run("Macro...", level);
}


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

macro "PSF Gallery view Action Tool - C00g V32ad  H20f07700 H2hfh7700 Ceee H60a08300 H6hah8e00 C0g0 V438b Cgg0 V5468 Cg00 V6644"
{

//get info
fn=getInfo("image.filename");
rename("temp");
getDimensions(x, y, channels, slices, frames);

Stack.setSlice(slices/2);

run("Brightness/Contrast...");
resetMinAndMax();


sx=(x/10);
sy=y-(y/10);

getVoxelSize(px, py, pz, units);
factor=1;
if (units=="nm"){
	factor=1000;
}

Scalelength=floor(1*factor);

Dialog.create("Ortho PSF");
  Dialog.addMessage("Output format");
  Dialog.addNumber("Image border width in pixels:", 2);
  Scale = newArray("Yes", "No");
  Dialog.addNumber("scale bar length:", Scalelength);  
  Dialog.addMessage("                                   units:     "+ units);  
  Dialog.addRadioButtonGroup("Do you want to add a scale bar?", Scale, 1, 1, "Yes");
Dialog.show;

bw=Dialog.getNumber(); 
Sc = Dialog.getRadioButton();
scalelength=Dialog.getNumber(); 
sunits=Dialog.getString(); 

//xz1="XZ " + floor(y/2);
//yz1="YZ "+ floor(x/2);
bd=bitDepth();
if (channels>1){
	exit("Image only works on one channel");
}
//else if (bd!=16){
//	exit("Image not 16-bit"); 
//}



setLocation(200,200,500,500);


run("Orthogonal Views");

title = "Get info";
msg = "Select x, y & z position in main image\n \n then select OK to continue";
waitForUser(title, msg);

////




Imtitles=getList("image.titles");
for (im=0;im<Imtitles.length;im++){
if (startsWith(Imtitles[im], "YZ ")){
    yz=Imtitles[im];
}
if (startsWith(Imtitles[im], "XZ ")){
	xz=Imtitles[im];
}
}



selectWindow(xz);
run("Remove Overlay");
run("Duplicate...", " ");
rename("3");

selectWindow(yz);
run("Remove Overlay");
run("Duplicate...", " ");
rename("2");


getDimensions(extraw, extrah, channels, slices, frames);
mode=toString(bd)+"-bit greyscale";
newImage("4", mode, extraw, extraw, 1, 1, 1);


selectWindow("temp");
run("Enhance Contrast", "saturated=0.35");


selectWindow("temp");
run("Duplicate...", "title=1");
run("Hide Overlay");
//selectWindow("temp");
//close();



//create rows
selectWindow("1");	
getDimensions(x, y, channels, slices, frames);
newImage("border", mode, bw, y, 1, 1, 1);
setColor("white");
fill();

t="stack1=[1] stack2=[2]";
tb="stack1=[1] stack2=[border]";
run("Combine...", tb);
rename("1");
run("Combine...", t);
rename("1");	



selectWindow("3");	
getDimensions(x, y, channels, slices, frames);
newImage("border", mode, bw, y, 1, 1, 1);
setColor("white");
fill();

t="stack1=[3] stack2=[4]";
tb="stack1=[3] stack2=[border]";
run("Combine...", tb);
rename("3");
run("Combine...", t);
rename("2");	



//join rows
getDimensions(x, y, channels, slices, frames);
newImage("border", mode, x, bw, 1, 1, 1);
setColor("white");
fill();

t="stack1=[1] stack2=[2] combine";
tb="stack1=[1] stack2=[border] combine";
run("Combine...", tb);
rename("1");
run("Combine...", t);
rename("Ortho view (orig) " + fn);	
newscale="distance=1 known=" + px + " pixel=1 unit=" + units;
run("Set Scale...", newscale);

//exit();

run("royal");
//resetMinAndMax();
//run("Scale Bar...", "width=10 height=2 font=12 color=White background=None location=[Upper Left]");
px5=px/5;
pz5=pz/5;
run("Scale...", "x=5 y=5 width=770 height=770 interpolation=Bilinear average create title=scaled up");
newscale="distance=1 known=" + px5 + " pixel=1 unit=" + units;
run("Set Scale...", newscale);
rename("Ortho view (5x scale) " + fn);	

if (Sc=="Yes")
{
makePoint(sx*5, sy*5);
len="width=" + scalelength + " height=4 font=18 color=White background=None location=[At Selection]";
run("Scale Bar...", len );
run("Select None");

setTool("rectangle");
}
}

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


macro "Heat Map from Results Table Action Tool - C000 T0708H T7708e Tc708a Th708t T1h08M T9h08a Teh08p"
{
//initialise
roiManager("Reset");
roiManager("UseNames", "true");
run("Labels...", "color=white font=12 show use");
run("Colors...", "foreground=white background=black selection=white");

//arrays
format=newArray("manual","15 well","24 well","48 well","96 well","384 well");
let=newArray("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P");
rowindex="ABCDEFGHIJKLMNOP";
num=newArray("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24");
Shapes=newArray("oval","rectangle");
lut_list=newArray("royal","Heat map","Red Hot","Leica glow","mpl-Inferno","mpl-magma");
Well=0;

waitForUser("","Select results table");
rw=getInfo("window.title");

if (isOpen(rw)==true){
result_number=getValue("results.count");
header_list=split(Table.headings);
}else {
	exit("no results table");
}

//dialog
Dialog.create("Options");
Dialog.addRadioButtonGroup("Plate Format", format, 1, 6, format[0]);
Dialog.addMessage("If manual then select rows and columns");
Dialog.addChoice("Number of Rows", let);
Dialog.addChoice("Number of Columns", num);
Dialog.addRadioButtonGroup("Well Shape", Shapes, 1, 2, Shapes[0]);
Dialog.addChoice("Select parameter", header_list);
Dialog.addCheckbox("non intensity measurement", false);
Dialog.addNumber("Scale Factor", 2);
Dialog.addChoice("Look-up Table", lut_list);
Dialog.addCheckbox("display Values", true)
Dialog.show();

//responses
plate_format=Dialog.getRadioButton();
InYlet=Dialog.getChoice();
InX=parseInt(Dialog.getChoice());
shape=Dialog.getRadioButton();
parameter=Dialog.getChoice();
non_int=Dialog.getCheckbox();
display_factor=Dialog.getNumber();
disp_lut=Dialog.getChoice();
Show_values=Dialog.getCheckbox();


if (plate_format=="15 well"){
	InYlet="C";
	InX=5;
} else if (plate_format=="24 well"){
	InYlet="D";
	InX=6;	
} else if (plate_format=="48 well"){
	InYlet="F";
	InX=8;	
} else if (plate_format=="96 well"){
	InYlet="H";
	InX=12;	
} else if (plate_format=="384 well"){
	InYlet="P";
	InX=24;	
}


//look up Y value
InY=indexOf(rowindex,InYlet)+1;

//data array
data=newArray(InX*InY);

//get  data
res=result_number;
if (result_number>InX*InY){
	res=InX*InY;
}
for (roi=0;roi<res;roi++){
data[roi]=(getResult(parameter,roi));
}
Array.getStatistics(data, data_min, data_max, mean, stdDev);


//create map image
newImage("Heat Map Data", "16-bit black", 40*InX*display_factor+40, 40*InY*display_factor+40, 1);

//create well format
for (welly=0;welly<InY;welly++){
for (wellx=0;wellx<InX;wellx++){
run("Specify...", "width="+30*display_factor+" height="+30*display_factor+" x="+15*display_factor+wellx*40*display_factor+" y="+15*display_factor+welly*40*display_factor+" "+shape);
roiManager("Add");
roiManager("Select",Well);
roiManager("rename",let[welly]+num[wellx]);
Well=Well+1;
}
}


//draw wells
well=0;
for (welly=0;welly<InY;welly++){
for (wellx=0;wellx<InX;wellx++){
//display values
if (Show_values==true){
	setFont("SansSerif", 7*display_factor);	
	drawString(data[well], 15*display_factor+wellx*40*display_factor, 14*display_factor+(welly+1)*40*display_factor);
}
//apply values
roiManager("select", well);
run("Set...", "value="+data[well]);
if (non_int==true){
run("Set...", "value="+data[well]/data_max*60000);
}else{
	run("Set...", "value="+data[well]);
}
well=well+1;
}
}

//finish up
setMinAndMax(data_min, data_max);
setFont("SansSerif", 9*display_factor, "bold");
drawString("Intensity Heat map of "+parameter, 10*display_factor ,11*display_factor);
run(disp_lut);
run("Select None");

}





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

macro "Quick Data Plot Action Tool - Cg00 L1dh4 C000 T3408P T9408l Tb408o Tg408t T3g08d T9g08a Teg08t Thg08a C00g L000h L0hhh"
{

//get data table
waitForUser("Select Data Table then press ok");
nres=Table.size;
add_title_to_plot=false;


//get headings
All_Titles=split(Table.headings, "\t");
if (All_Titles[0]==" "){
All_Titles[0]="none";
}

//arrays
Included_Y_Titles=newArray(0);
Included_Y_Colours=newArray(0);
Included_Y_Type=newArray(0);
Linecolors=newArray("black","red","green","blue","magenta","cyan","yellow");
Inverse_Linecolors=newArray("black","cyan","magenta","yellow","green","red","blue");
Graph_type=newArray("line","connected circle","filled","bar","separated bar","circle","box","triangle","diamond","cross","x","dot","error bars");
All_Data=newArray(0);


//get x axis
Dialog.create("X axis");
	Dialog.addChoice("Select X-axis data", All_Titles);
Dialog.show();

X_axis_response=Dialog.getChoice();
xtitle=X_axis_response;
if (X_axis_response=="none"){
	xtitle="";
}

//select Y data
Dialog.create("Y Data");
Dialog.addMessage("Select Y-data to include in the plot", 16, "Red");
Dialog.addMessage("Column                                                                      Change Title Name?                    Plot Type                Colour",14, "blue");
for (ct=0;ct<All_Titles.length;ct++){
	if (X_axis_response!=All_Titles[ct] && All_Titles[ct]!="none"){
	Dialog.addCheckbox(All_Titles[ct] , false);
	Dialog.setInsets(-25, 0, 0);
	Dialog.addString("", All_Titles[ct],25);
	Dialog.setInsets(-28, 210, 0);
	Dialog.addChoice("", Graph_type);
	Dialog.setInsets(-27, 335, 10);
	Dialog.addChoice("", Linecolors);
}
}

Dialog.addMessage("Axis Titles",14,"blue");
Dialog.addString("X-Axis title", xtitle,30);
Dialog.addString("Y-Axis title", "Intensity",30);
Dialog.setInsets(-52, 20, 0);
Dialog.addCheckbox("fill Bar or Symbol", true);
Dialog.setInsets(0, 0, 0);
Dialog.addNumber("Line width or Symbol size", 1);
Dialog.show();


//get Y data and titles
ColName=" -- ";
offset=0.5;

Title_responses=newArray(All_Titles.length);
for (ct=0;ct<All_Titles.length;ct++){
	if (X_axis_response!=All_Titles[ct] && All_Titles[ct]!="none"){		
	Title_responses[ct]=Dialog.getCheckbox();
	Tname=Dialog.getString();	
	if (Title_responses[ct]==true){
	Add_Title=All_Titles[ct];
	Included_Y_Titles=Array.concat(Included_Y_Titles, Add_Title);
	Selected_Data=Table.getColumn(All_Titles[ct]);
	All_Data=Array.concat(All_Data,Selected_Data);
	ColName=ColName+Tname+" -- ";	
	}
	Plot_type=Dialog.getChoice();
	if (Title_responses[ct]==true){
	Included_Y_Type=Array.concat(Included_Y_Type,Plot_type);
	if (Plot_type=="line" || Plot_type=="connected circle" || Plot_type=="filled" || Plot_type=="bar"){
		offset=0;
	}
	}	
	Add_Color=Dialog.getChoice();
	if (Title_responses[ct]==true){
	Included_Y_Colours=Array.concat(Included_Y_Colours,Add_Color);
	}
	}
}
new_x_title=Dialog.getString();
new_y_title=Dialog.getString();
fill_symbol=Dialog.getCheckbox();
symbol_size=Dialog.getNumber();


//x-axis scale and title
if (X_axis_response=="none"){
X_axis=Array.getSequence(nres);	
X_axis_response=new_x_title;

}else{
X_axis=Table.getColumn(X_axis_response);
}
TabRows=X_axis.length;



//x axis text
if (isNaN(X_axis[0])){
	add_title_to_plot=true;
	X_Axis_text_array="{"+X_axis[0];	
for (res=1;res<nres;res++){
	X_Axis_text_array=X_Axis_text_array+","+X_axis[res];
}
X_Axis_text_array=X_Axis_text_array+"}";
X_axis_response=X_Axis_text_array;
X_axis=Array.getSequence(nres);	
}
Array.getStatistics(X_axis, X_axis_Min, X_axis_Max, X_axis_Mean, X_axis_StdDev);

// Y data info
Array.getStatistics(All_Data, All_Min, All_Max, All_Mean, All_StdDev);
if (All_Data.length<1){
	exit("No data selected");
}



//get plot details
Dialog.create("Plot size");
  Dialog.addMessage("Select Plot options");
  Dialog.addNumber("Low Y value ", All_Min, 0, 6," " );
  Dialog.addNumber("High Y value ", All_Max, 0, 6," " );
  Dialog.addMessage("Enter dimensions of plot window");
  Dialog.addNumber("X dimension ", 650, 0, 4," pixels" );
  Dialog.addNumber("Y dimension ", 350, 0, 4," pixels" );
  option = newArray("yes","No");
  Dialog.addChoice("Invert graph", option, "No");
Dialog.show;

All_Min = Dialog.getNumber(); 
All_Max = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
Inv= Dialog.getChoice();


//invert graph colours
if(Inv=="Yes"){
plotCol=newArray(Included_Y_Colours.length);
for (c=0;c<Included_Y_Colours.length;c++){
for (i=0;i<6;i++){
	if (Included_Y_Colours[c]==Linecolors[i]){
		plotCol[c]=Inverse_Linecolors[i];
}
}
}
Included_Y_Colours=plotCol;
}

//plot 
Plot.create("Data Plot", X_axis_response, new_y_title);
    Plot.setFrameSize(plotsizex, plotsizey);
    Plot.setLimits(X_axis_Min-offset, X_axis_Max+offset, All_Min-(All_Max-All_Min)*0.05, All_Max+(All_Max-All_Min)*0.05);

text_pos=0.025;
for (plot=0;plot<Included_Y_Titles.length;plot++){
	PartChannel=Array.slice(All_Data,TabRows*plot,TabRows+TabRows*plot);
Yes_fill="";
if (fill_symbol==true){
	Yes_fill=Included_Y_Colours[plot];
}		     
    Plot.add(Included_Y_Type[plot],X_axis, PartChannel);
    Plot.setStyle(plot*2, Included_Y_Colours[plot]+","+Yes_fill+","+symbol_size+","+Included_Y_Type[plot]);
    Plot.addText(Included_Y_Titles[plot], text_pos, 0);
    text_pos=text_pos+(Included_Y_Titles[plot].length)*6/plotsizey;
}

if (add_title_to_plot==true){
	Plot.setColor("black");
	Plot.addText(new_x_title, 0.5-(new_x_title.length)*6/plotsizey*0.5, 1.1);
}
Plot.show();


//invert graph
if(Inv=="Yes"){
run("Invert", "stack");
}

}


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

macro " Create Frame by Frame Plot from Data Action Tool - C0g0 L1h43 L43hd C00g L1d6e L6eh4 Cg00 L1649 L49h8 C000 T2408f T6408r T9408o Te408m T3g08d T9g08a Teg08t Thg08a  L000h L0hhh"
{
//get data table
res_table=getList("window.titles");
res_table=Array.deleteValue(res_table, "Log");
  if (res_table.length==0){
     exit("No results windows are open");
}
Dialog.create("Results Window");
Dialog.addChoice("Select Results Table", res_table);
Dialog.show();

result_tables=Dialog.getChoice();
selectWindow(result_tables);

//get colume names
All_Titles=split(Table.headings, "\t");
if (All_Titles[0]==" "){;
All_Titles=Array.slice(All_Titles,1,All_Titles.length);	
}
//Base_Title="Frame No.";
//All_Titles=Array.concat(Base_Title,All_Titles);

//arrays
Included_Y_Titles=newArray(0);
Included_Y_newname=newArray(0);
Included_Y_Colours=newArray(0);
Linecolors=newArray("black","red","green","blue","magenta","cyan","yellow");
Inverse_Linecolors=newArray("black","cyan","magenta","yellow","green","red","blue");
All_Data=newArray(0);

X_units="";
X_interval=1;

//get x axis
Dialog.create("X axis");
Dialog.addChoice("Select X axis", All_Titles);
Dialog.show();
X_title=Dialog.getChoice();


X_axis=Table.getColumn(X_title);
Array.getStatistics(X_axis, X_axis_Min, X_axis_Max, X_axis_Mean, X_axis_StdDev);
TabRows=X_axis.length;


//select Y data and titles
Y_title="Intensity";

Dialog.create("Data");
Dialog.addMessage("X axis: "+ X_title);
Dialog.addString("X axis Title ", X_title);
Dialog.addString("Y axis Title ", Y_title);
Dialog.setInsets(5, 0, 25);
Dialog.addMessage("Y-Axis data to include and plot line colour \n");
for (ct=0;ct<All_Titles.length;ct++){
	if (X_title!=All_Titles[ct]){
	Dialog.setInsets(0, 0, -30);	
	Dialog.addCheckbox(All_Titles[ct] , false);
	Dialog.setInsets(0, 180, -32);
	Dialog.addString("Change Name? ", All_Titles[ct],18);
	Dialog.setInsets(0, 180, 12);
	Dialog.addChoice("", Linecolors);
}
}
Dialog.show();
new_X_title=Dialog.getString();
Y_title=Dialog.getString();
Title_responses=newArray(All_Titles.length);
for (ct=0;ct<All_Titles.length;ct++){
	if (X_title!=All_Titles[ct]){		
	Title_responses[ct]=Dialog.getCheckbox();
	new_name=Dialog.getString();	
	if (Title_responses[ct]==true){
	Add_Title=All_Titles[ct];
	Included_Y_Titles=Array.concat(Included_Y_Titles, Add_Title);
	Selected_Data=Table.getColumn(All_Titles[ct]);
	All_Data=Array.concat(All_Data,Selected_Data);
	Included_Y_newname=Array.concat(Included_Y_newname, new_name);
	}
	Add_Color=Dialog.getChoice();
	if (Title_responses[ct]==true){
	Included_Y_Colours=Array.concat(Included_Y_Colours,Add_Color);
	}
	}
}
// Y data info
Array.getStatistics(All_Data, All_Min, All_Max, All_Mean, All_StdDev);
X_title=new_X_title;

//get plot details
Dialog.create("Plot size");
  Dialog.addMessage("Select Plot options");
  Dialog.addNumber("Low intensity value ", All_Min, 0, 6," " );
  Dialog.addNumber("High intensity value ", All_Max, 0, 6," " );
  Dialog.addMessage("Enter dimensions of plot window");
  Dialog.addNumber("X dimension ", 650, 0, 4," pixels" );
  Dialog.addNumber("Y dimension ", 350, 0, 4," pixels" );
  Dialog.addMessage("Additional options");
  Dialog.setInsets(-6, 200, 20);
  Dialog.addCheckbox("Edit axis titles, tick marks and grids", false);
  option = newArray("yes","No");
  Dialog.addChoice("Invert graph", option, "No");
  Dialog.addNumber("Line width ", 2, 0, 4," pixels" );
Dialog.show;

All_Min = Dialog.getNumber(); 
All_Max = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
change_plot=Dialog.getCheckbox();
Inv= Dialog.getChoice();
plotlinewidth = Dialog.getNumber(); 





//advanced plot options
if (change_plot==true){
Dialog.create("Plot Options");
Dialog.addMessage("Axis titles");
  Dialog.addString("X-axis title:",X_title);
  Dialog.addNumber("Change frame interval value",X_axis[1]-X_axis[0]);
  Dialog.addString("X-axis units", "");
  Dialog.addString("Y-axis title:",Y_title);
Dialog.addMessage("Grids and tick marks");
  format=newArray("grid X","grid Y","major ticks X", "major ticks Y", "minor ticks X", "minor ticks Y","numbers X", "numbers Y");
  defaults=newArray(true,true,true,true,true,true,true,true);
  Dialog.addCheckboxGroup(4,2,format,defaults);
  Dialog.addMessage("interval between numbers, major ticks and grid lines");
  Dialog.addNumber("interval in X", 0);
  Dialog.addNumber("interval in Y", 0);
Dialog.show(); 

X_title= Dialog.getString();
X_interval=Dialog.getNumber();
X_units=Dialog.getString();
Y_title= Dialog.getString();
gX=Dialog.getCheckbox();
gY=Dialog.getCheckbox();
MatX=Dialog.getCheckbox();
MatY=Dialog.getCheckbox();
MitX=Dialog.getCheckbox();
MitY=Dialog.getCheckbox();
NumX=Dialog.getCheckbox();
NumY=Dialog.getCheckbox();
xint=Dialog.getNumber();
yint=Dialog.getNumber();

opts="1100"+toString(MitY)+toString(MitX)+"00"+toString(gY)+toString(gX)+toString(MatY)+toString(MatX)+toString(NumY)+toString(NumX);
}

if(X_units!=""){
X_units=" ("+X_units+") ";
}


for (fr=0;fr<X_axis.length;fr++){
	Txt=isNaN(X_axis[fr]);
	if (Txt==true){
	X_axis[fr]=fr;
	}
	X_axis[fr]=(X_axis[fr]*X_interval);	
	
}
Array.getStatistics(X_axis, X_axis_Min, X_axis_Max, X_axis_Mean, X_axis_StdDev);

//invert graph colours
if(Inv=="Yes"){
plotCol=newArray(Included_Y_Colours.length);
for (c=0;c<Included_Y_Colours.length;c++){
for (i=0;i<6;i++){
	if (Included_Y_Colours[c]==Linecolors[i]){
		plotCol[c]=Inverse_Linecolors[i];
}
}
}
Included_Y_Colours=plotCol;
}


//main plot and results
//setBatchMode(true);
frm=1;
for (plot_part=0;plot_part<X_axis.length;plot_part++){
        Plot.create("Plot - frame:"+plot_part , X_title+X_units, Y_title);
	     if(change_plot==true){
        Plot.setFormatFlags(opts);
        Plot.setOptions("xinterval="+xint+" yinterval="+yint+"");
        }        Plot.setLimits(X_axis_Min, X_axis_Max, All_Min-(All_Max-All_Min)*0.05, All_Max+(All_Max-All_Min)*0.05);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);

for (plot=0;plot<Included_Y_Titles.length;plot++){
		PartChannel=Array.slice(All_Data,0+TabRows*plot,0+TabRows*plot+frm);  
		Plot.setColor(Included_Y_Colours[plot]);		     
        Plot.add("line",X_axis, PartChannel);
        Plot.addText(Included_Y_newname[plot], 0.25*plot, 0);
}    
        Plot.setColor("#000000");    
        Plot.drawLine((X_axis[plot_part]), All_Min-(All_Max-All_Min)*0.05, (X_axis[plot_part]), All_Max+(All_Max-All_Min)*0.05);        
Plot.show();
frm=frm+1;
}

//combine plots
run("Images to Stack", "name=Time plot_part title=[] use");
setBatchMode(false);

//invert graph
if(Inv=="Yes"){
run("Invert", "stack");
}

rename("Frame Plot");

}


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

macro "Difference of Gaussians Filter Action Tool - C00g T0409G T64091 T8g09G Tfg092 Cg00 L3ae0"
{

fn=getTitle();

Dialog.create("Options");
vs=Array.getSequence(50);
Dialog.addMessage("Difference of Gaussians \n \n - values must be different for each image");
Dialog.addMessage("Image 1");
Dialog.addChoice("Gaussian Blur Sigma value", vs);
Dialog.addCheckbox("Scaled Units", false);
Dialog.addMessage("Image 2");
Dialog.addChoice("Gaussian Blur Sigma value", vs);
Dialog.addCheckbox("Scaled Units", false);
Dialog.show();

v1=Dialog.getChoice();
v1su=Dialog.getCheckbox();
v2=Dialog.getChoice();
v2su=Dialog.getCheckbox();

if(v1==v2){
	exit("Sigma values must be different for each image");
}

su1="";
su2="";
if (v1su==true){
	su1="Scaled";
}
if (v2su==true){
	su2="Scaled";
}

run("Duplicate...", "title=copy duplicate");
run("32-bit");
run("Duplicate...", "title=G1 duplicate");
run("Gaussian Blur...", "sigma="+v1+" "+su1+" stack");// original blur
selectWindow("copy");
run("Duplicate...", "title=G2 duplicate");
run("Gaussian Blur...", "sigma="+v2+" "+su2+" stack");//subtract blur
imageCalculator("Subtract create stack", "G1","G2");
selectWindow("Result of G1");
rename(fn+" Difference of Gaussians "+v1+"-"+v2);
run("16-bit");
selectWindow("G1");
close();
selectWindow("G2");
close();
selectWindow("copy");
close();
}



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

macro "Save images from a stack Action Tool - C000 T0508S T6508t T9508a Td508c Th408k T0f08S T6f08a Tbf08v Tgf08e"
{

fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
run("Select None");


Output_name=getString("Enter output file name", fn+" Image");

//select location where images/results are to be stored
output = getDirectory("Output ditrectory for individual images");


nm="_00";
for (Im=1;Im<=ImageSlices;Im++){
	if (Im>9){
	nm="_0";
	}
	if (Im>99){
	nm="_";
	}
Stack.setSlice(Im);
run("Duplicate...", "title=TempImage");
	
//save drawing or image
out = output +Output_name+nm+toString(Im);
saveAs("Tiff",out);
close();
}

}

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

macro "Time Info Spark Image (LSM format) Action Tool - C000 T0608S T6608p Tb608a Tg608r Tj608k T1h08M T9h08e Tfh08t Tih08a"
{

run("Set Measurements...", "area mean min display redirect=None decimal=9");
fn=getTitle();

Meta=getMetadata("Info");
st=indexOf(Meta, "TimeInterval");
end= indexOf(Meta, "Timer");
Meta=substring(Meta, st, end);

frame_data=split(Meta, "\n");
Frame_interval=frame_data[0];
frame_data=Array.deleteIndex(frame_data, 0);
sub_meta=indexOf(frame_data[0], "=")+2;

for (fr=0;fr<frame_data.length;fr++){
	frame_data[fr]=parseFloat(substring(frame_data[fr], sub_meta));
}
zr=frame_data[0];

for (fr=0;fr<frame_data.length;fr++){
	frame_data[fr]=frame_data[fr]-zr;
}

Table.create(fn+" Frame Info");
Table.showRowNumbers(true);
Table.setLocationAndSize(200, 200, 500, 600);
Table.setColumn("Frame time", frame_data);
Table.set("Frame rate", 0, Frame_interval);

run("Set Measurements...", "area mean min display redirect=None decimal=3");

}

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