//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 "Ratio Time Series Plots Select Channel Action Tool - Cg33 H060hh60 C2g2 Hhh0hh60 C000 R06ha T0508r T4508a Ta508t Td508i Tg508o T3e08p T8e08l Tae08o Tfe08t "
{

//initialise
run("Clear Results");
setTool("oval");
fn=getTitle();
getDimensions(width, height, channels, slices, frames);

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

//get bit depth
bit=bitDepth();
yscalelim=pow(2, bit);


// create array for all data
ChannelData=newArray(frames*channels);
Ratio=newArray(frames);

//test for time series
if (frames==1 && slices==1){
	exit("This is not a time series");
}
if (frames>1 && slices>1){
	exit("This macro does not work on a Z stack time series");
}
if (frames==1 && slices!=1){
con=getBoolean("Image has only 1 frame, but " + slices + " slicess, do you want to convert slices to frames");
if (con==1){
run("Stack to Hyperstack...", "order=xyczt(default) channels=1 slices=" + frames + " frames=" + slices + " display=Color");	
getDimensions(width, height, channels, slices, frames);
Stack.setTUnit("frame");
}
}
if (channels<2){
	exit("Image has only one channel");
}

//select channels
Dialog.create("Title")
  Dialog.addMessage("Slect Channels to Ratio");
  Dialog.addMessage("ratio = First Channel / Second Channel");
  Dialog.addChoice("First Channel:", list, list[0]);
  Dialog.addChoice("Second Channel:", list, list[1]);
  Dialog.addCheckbox("Join Intensity and Raiometric plots",true);
Dialog.show(); 

list[0]=Dialog.getChoice();
list[1]=Dialog.getChoice();
JoinPlots=Dialog.getCheckbox();

//error check
if (list[0]==list[1]){
	exit("The same channel has been selected for comparison");
}

//get plot details
Dialog.create("Plot size");
  Dialog.addMessage("Select Plot options: \n - if the colours appear wrong, you may need to re-set the LUT's\n - use the Change channel LUT's macro");
  range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
  Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
  Dialog.addNumber("Low intensity value ", 0, 0, 6," pixels" );
  Dialog.addNumber("High intensity value ", yscalelim, 0, 6," pixels" );
  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("Set line width");
  Dialog.addNumber("Line width ", 1, 0, 4," pixels" );  
Dialog.show;

//responses
rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  
ymin=0;


//draw roi and get data
title = "Draw Profile";
msg = "Draw Roi\n \n then select OK to continue";
waitForUser(title, msg);
roiManager("Reset");
roiManager("Add");
roiManager("Multi Measure");
for (i=0;i<frames*channels;i++){
  ChannelData[i]=getResult("Mean1", i);
}
selectWindow("Results");
run("Close");


//get 2 channel data and get Ratio
FirstChannel=newArray(frames);
SecondChannel=newArray(frames);
Ratio=newArray(frames);

ad=0;
for (t=0;t<frames*channels;t++){
FirstChannel[ad]=ChannelData[t+parseInt(list[0])-1];
SecondChannel[ad]=ChannelData[t+parseInt(list[1])-1];
Ratio[ad]=FirstChannel[ad]/SecondChannel[ad];
t=t+channels-1;
ad=ad+1;
}


//get x range
Frame_Interval=newArray(frames);
Fr=Stack.getFrameInterval();
if (Fr==0){
	Fr=1;
}
Stack.getUnits(X, Y, Z, Time, Value);
for (fi=1;fi<frames;fi++){
Frame_Interval[fi]=fi * Fr;
} 
Array.getStatistics(Frame_Interval, min, xscalelen, mean, stdDev);

//get y range
Array.getStatistics(FirstChannel, flowlevel, fhighlevel, fmean, fstdDev);
Array.getStatistics(SecondChannel, slowlevel, shighlevel, smean, sstdDev);
highlevel=fhighlevel;
lowlevel=flowlevel;
if (highlevel<shighlevel){
	highlevel=shighlevel;
}
if (lowlevel>slowlevel){
	lowlevel=slowlevel;
}
extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;


//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//print intensity and ratio data
for (row=0;row<frames;row++){
	setResult("Frame Interval (" + Time + ")", row, Frame_Interval[row]);
	setResult(" Channel "+list[0]+" Intensity", row, FirstChannel[row]);
	setResult(" Channel "+list[1]+" Intensity", row, SecondChannel[row]);
	setResult("Ratio Chan "+list[0]+" / Chan "+list[1], row, Ratio[row]);
}

//rename results
IJ.renameResults("Results",fn+" - Intensity Data");


//Channel intensity plots
Channel=newArray(frames);
Plot.create(fn+" - Time Intensity Plot", "Time (" + Time + ")", "Intensity");
        Plot.setLimits(0, xscalelen, ymin, ymax);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);
Stack.setChannel(list[0]); 
col=lookup();
		Plot.setColor(col);     
        Plot.add("line",Frame_Interval, FirstChannel);
        Plot.addText("Channel " + list[0], 0, 0);
Stack.setChannel(list[1]); 
col=lookup();
		Plot.setColor(col);     
        Plot.add("line",Frame_Interval, SecondChannel);
		Plot.addText("Channel " + list[1], 0.1, 0);
Plot.show();
rename("Intensity Plots of "+fn);


//plot ratio
Array.getStatistics(Ratio, Rmin, Rmax, Rmean, RstdDev);
Plot.create(fn+" - Time Ratio Plot", "Time (" + Time + ")", "Ratio Channel "+list[0]+" / Channel "+list[1]);
        Plot.setLimits(0, xscalelen, Rmin-(Rmin*0.1), Rmax+(Rmax*0.1));
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);
		Plot.setColor("Magenta");     
        Plot.add("line",Frame_Interval, Ratio);
Plot.show();
rename("Ratio of "+fn);


//combine plots
if (JoinPlots==true){
getDimensions(pwidth, pheight, pchannels, pslices, pframes);
run("Canvas Size...", "width=pwidth height="+pheight+2+" position=Bottom-Center zero");
run("Combine...", "stack1=[Intensity Plots of "+fn+"] stack2=[Ratio of "+fn+"] combine");
rename(fn+" Intensity and Ratio Plots");
}

//end

// select colour
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 "Ratio Time Plots (channel select/multi ROI) Action Tool - Cg33 H060hh60 C2g2 Hhh0hh60 C000 R06ha T1508R T7508O Td508I  T3e08p T8e08l Tae08o Tfe08t "
{

//initialise
run("Clear Results");
setTool("oval");
fn=getTitle();
getDimensions(width, height, channels, slices, frames);
n=roiManager("Count");
roiManager("Deselect");


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

//get bit depth
bit=bitDepth();
yscalelim=pow(2, bit);


//test for time series
if (frames==1 && slices==1){
	exit("This is not a time series");
}
if (frames>1 && slices>1){
	exit("This macro does not work on a Z stack time series");
}
if (frames==1 && slices!=1){
con=getBoolean("Image has only 1 frame, but " + slices + " slicess, do you want to convert slices to frames");
if (con==1){
run("Stack to Hyperstack...", "order=xyczt(default) channels=1 slices=" + frames + " frames=" + slices + " display=Color");	
getDimensions(width, height, channels, slices, frames);
Stack.setTUnit("frame");
}
}
if (channels<2){
	exit("Image has only one channel");
}


//select channels
Dialog.create("Title")
  Dialog.addMessage("Slect Channels to Ratio");
  Dialog.addMessage("ratio = First Channel / Second Channel");
  Dialog.addChoice("First Channel:", list, list[0]);
  Dialog.addChoice("Second Channel:", list, list[1]);
  Dialog.addCheckbox("Join Intensity and Raiometric plots",true);
Dialog.show(); 

list[0]=Dialog.getChoice();
list[1]=Dialog.getChoice();
JoinPlots=Dialog.getCheckbox();


//eror check
if (list[0]==list[1]){
	exit("The same channel has been selected for comparison");
}


//get plot details
Dialog.create("Plot size");
	opt = newArray("Yes","No");
	if (n>0){
	Dialog.addChoice("Do you want to keep existing ROI's", opt, "Yes")
	}
	Dialog.addMessage("Select Plot options: \n - if the colours appear wrong, you may need to re-set the LUT's\n - use the Change channel LUT's macro");
	range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
	Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
	Dialog.addNumber("Low intensity value ", 0, 0, 6," pixels" );
	Dialog.addNumber("High intensity value ", yscalelim, 0, 6," pixels" );
	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("Set line width");
	Dialog.addNumber("Line width ", 1, 0, 4," pixels" );  
Dialog.show;
if (n>0){
answer=Dialog.getChoice();
if (answer=="No"){
roiManager("Reset");	
}
}
//get responses
rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  
ymin=0;



//draw roi's
title = "Draw Rois";
msg = "Add ROI's - draw and press [t] \n \n then select OK to continue";
waitForUser(title, msg);

n=roiManager("Count");
roiManager("deselect");
roiManager("Remove Channel Info");
roiManager("Remove Slice Info");
roiManager("Remove Frame Info");

//get all intensity data
data=frames*channels;
ChannelData=newArray(frames*channels*n);
roiManager("Multi Measure");
for (roi=0;roi<n;roi++){
for (i=0;i<data;i++){
	
	ChannelData[i+(data*roi)]=getResult("Mean"+roi+1, i);
}
}
selectWindow("Results");
run("Close");


//get 2 channel data and get Ratio
FirstChannel=newArray(frames*n);
SecondChannel=newArray(frames*n);
Ratio=newArray(frames*n);

ad=0;
for (t=0;t<frames*channels*n;t++){
FirstChannel[ad]=ChannelData[t+parseInt(list[0])-1];
SecondChannel[ad]=ChannelData[t+parseInt(list[1])-1];
Ratio[ad]=FirstChannel[ad]/SecondChannel[ad];
t=t+channels-1;
ad=ad+1;
}



//get x range
Frame_Interval=newArray(frames);
Fr=Stack.getFrameInterval();
if (Fr==0){
	Fr=1;
}
Stack.getUnits(X, Y, Z, Time, Value);
for (fi=1;fi<frames;fi++){
Frame_Interval[fi]=fi * Fr;
} 
Array.getStatistics(Frame_Interval, min, xscalelen, mean, stdDev);


//get y range
Array.getStatistics(FirstChannel, flowlevel, fhighlevel, fmean, fstdDev);
Array.getStatistics(SecondChannel, slowlevel, shighlevel, smean, sstdDev);
highlevel=fhighlevel;
lowlevel=flowlevel;
if (highlevel<shighlevel){
	highlevel=shighlevel;
}
if (lowlevel>slowlevel){
	lowlevel=slowlevel;
}
extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;


//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//print intensity data
for (t=0;t<frames;t++){
      setResult("Frame Interval (" + Time + ")", t, Frame_Interval[t]);
}
for (roi=0;roi<n;roi++){
for (row=0;row<frames;row++){
	setResult("Roi "+roi+1+" Channel "+list[0]+" Intensity", row, FirstChannel[row+(frames*roi)]);
	setResult("Roi "+roi+1+" Channel "+list[1]+" Intensity", row, SecondChannel[row+(frames*roi)]);
	setResult("Roi "+roi+1+" Ratio (Chan "+list[0]+" / "+list[1]+")", row, Ratio[row+(frames*roi)]);
}
}


//intensity plot routine
Channel1=newArray(frames);
Channel2=newArray(frames);
Ratio1=newArray(frames);
Array.getStatistics(Ratio, Rmin, Rmax, Rmean, RstdDev);

for (roi=0;roi<n;roi++){
selectWindow(fn);
roiManager("Select",roi);

Channel1=Array.slice(FirstChannel,frames*roi,frames-1+(frames*roi));
Channel2=Array.slice(SecondChannel,frames*roi,frames-1+(frames*roi));
Ratio1=Array.slice(Ratio,frames*roi,frames-1+(frames*roi));

//Intensity plot routine
Plot.create("I_Roi "+roi+1, "Time (" + Time + ")", "Intensity");
       Plot.setLimits(0, xscalelen, ymin, ymax);
       Plot.setFrameSize(plotsizex, plotsizey);
       Plot.setLineWidth(plotlinewidth);
Stack.setChannel(list[0]); 
col=lookup();
		Plot.setColor(col);     
        Plot.add("line",Frame_Interval, Channel1);
        Plot.addText("Channel " + list[0], 0, 0);
Stack.setChannel(list[1]); 
col=lookup();
		Plot.setColor(col);     
        Plot.add("line",Frame_Interval, Channel2);
		Plot.addText("Channel " + list[1], 0.1, 0);
        Plot.setFontSize(16);
        Plot.setColor("Black"); 
        Plot.addText("Roi "+roi+1, 0.92, 0.09);
        Plot.setFontSize(12);
Plot.show();

//Ratio plot routine
Plot.create(fn+" Ratio Plot R_Roi "+roi+1, "Time (" + Time + ")", "Ratio Channel "+list[0]+" / Channel "+list[1]);
        Plot.setLimits(0, xscalelen, Rmin-(Rmin*0.1), Rmax+(Rmax*0.1));
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);
		Plot.setColor("Magenta");     
        Plot.add("line",Frame_Interval, Ratio1);    
//        Plot.addText("Channel " + list[0], 0, 0);
        Plot.setFontSize(16);
        Plot.setColor("Black"); 
        Plot.addText("Roi "+roi+1, 0.92, 0.09);
        Plot.setFontSize(12);
Plot.show();
} 


//join plots
if (n>1){
run("Images to Stack", "name=Stack title=I_Roi use");
rename(fn+" - Intensiy Plots");
run("Images to Stack", "name=Stack title=R_Roi use");
rename(fn+" - Ratio Plots");
}


//rename intensity data
IJ.renameResults("Results",fn+" - Intensity Data");



if (JoinPlots==true){
//combine plots
getDimensions(pwidth, pheight, pchannels, pslices, pframes);
run("Canvas Size...", "width=pwidth height="+pheight+2+" position=Bottom-Center zero");
run("Combine...", "stack1=["+fn+" - Intensiy Plots] stack2=["+fn+" - Ratio Plots] combine");
rename(fn+" Intensity and Ratio Plots");
}



// select colour
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;
}
}

}
///////////////////////////////////////////////////3

macro "Multi Roi (+15) Intensity Time Plots(single channel) Action Tool - C0g0 L1h43 L43hd C00g L1d6e L6eh4 Cg00 L1649 L49h8 C000 T3508R T9508O Tf508I T4f08+ T8g081 Teg085 L000h L0hhh"
{
//constants
run("Clear Results");
setTool("oval");
n=roiManager("Count");
roiManager("Show All with labels");


//get file info
getDimensions(width, height, channels, slices, frames);
fn=getTitle();

if (frames==1 && slices==1){
	exit("This is not a time series");
}
if (frames==1 && slices!=1){
con=getBoolean("Image has only 1 frame, but " + slices + " slicess, do you want to convert slices to frames");
if (con==1){
run("Stack to Hyperstack...", "order=xyczt(default) channels=1 slices=" + frames + " frames=" + slices + " display=Color");	
getDimensions(width, height, channels, slices, frames);

Stack.setTUnit("frame");
}
}

//get bit depth
bit=bitDepth();
yscalelim=pow(2, bit);

//get plot details
Dialog.create("Plot Details");
	opt = newArray("Yes","No");
	if (n>0){
		Dialog.addChoice("Do you want to keep existing ROI's", opt, "Yes")
	}
    Dialog.addMessage("Select Plot options: \n ");
    range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
    Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
    Dialog.addNumber("Low intensity value ", 0, 0, 6," pixels" );
    Dialog.addNumber("High intensity value ", yscalelim, 0, 6," pixels" );
    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("Set line width");
    Dialog.addNumber("Line width ", 1, 0, 4," pixels" );  
Dialog.show;

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


rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  
ymin=0;


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

// create arrays
n=roiManager("count");
roiManager("deselect");
roiManager("Remove Channel Info");
roiManager("Remove Slice Info");
roiManager("Remove Frame Info");
RoiData=newArray(frames*n);
RoiPlot=newArray(frames);


//reame and colour and roi's
for (i=0;i<n;i++){
roiManager("select", i);
name="ROI " + i+1;
roiManager("Rename", name);
Col=ColourGen();
//Roi.setStrokeColor(Col);
roiManager("Set Color", Col);
}
roiManager("Deselect");
roiManager("Multi Measure");

setBatchMode("hide");

for (roi=0;roi<n;roi++){
for (j=0;j<frames;j++){	
  RoiData[j+(frames*roi)]=getResult("Mean(ROI "+roi+1+")", j);
} 
}
selectWindow("Results");
run("Close");

//get y range
Array.getStatistics(RoiData, lowlevel, highlevel, mean, stdDev);
extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;


//get x range
Frame_Interval=newArray(frames);
Fr=Stack.getFrameInterval();
if (Fr==0){
	Fr=1;
}
Stack.getUnits(X, Y, Z, Time, Value);
for (fi=1;fi<frames;fi++){
Frame_Interval[fi]=fi * Fr;
} 
Array.getStatistics(Frame_Interval, min, xscalelen, mean, stdDev);
for (t=0;t<frames;t++){
      setResult("Frame Interval (" + Time + ")", t, Frame_Interval[t]);
}

//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//create plots and results
Channel=newArray(frames);

for (m=0;m<n;m++){
for (p=0;p<frames;p++){
  	  RoiPlot[p]=RoiData[p+(frames*m)];	
      name="Roi " + m+1;
      setResult(name, p, RoiPlot[p]);
}
		Plot.create(fn+" - Time Intensity Plot ROI "+m+1, "Time (" + Time + ")", "Intensity");
        Plot.setLimits(0, xscalelen, ymin, ymax);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);
		
		roiManager("Select",m);
	 	PlotCol=Roi.getStrokeColor;	
	 	if (PlotCol=="none"){
	 		roiManager("Set Color", "red");
	 		PlotCol="red";
	 	}
		Plot.setColor(PlotCol);     
        Plot.add("line",Frame_Interval, RoiPlot);
        Plot.show();
}


//join plots
if (n>1){
join=" title=["+fn+" - ROI Plots] ";
pl=1;
for (rplot=0;rplot<n;rplot++){
	join=join + " image"+pl+"=["+fn+" - Time Intensity Plot ROI "+rplot+1+"]";
	pl=pl+1;
}
run("Concatenate...", join);

//rename meta data
for (rplot=0;rplot<n;rplot++){
	Stack.setSlice(rplot+1);
    setMetadata("Label", fn+"  ROI "+rplot+1+"  ");
}

//project plots
selectWindow(fn+" - ROI Plots");
run("Z Project...", "projection=[Min Intensity]");
rename(fn+" All ROI Plot");

selectWindow(fn+" - ROI Plots");
Stack.setSlice(1);

setBatchMode("exit and display");

//finish up
IJ.renameResults("Results",fn+" - Intensity Data");
selectWindow(fn);
roiManager("Show All with labels");

//randon=m colour generator
function ColourGen(){
Red=floor(random*255);
RedHex=toHex(Red);
Green=floor(random*255);
GreenHex=toHex(Green);
Blue=floor(random*255);
BlueHex=toHex(Blue);
RoiCol="#"+RedHex+GreenHex+BlueHex;
return RoiCol;
}

}
}

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

macro "Shade correction (using Gaussian blur: Subtraction method) Action Tool - C0g0 F002h   C0e0 F202h   C0c0 F402h   C0a0 F602h   C090 F802h   C070 Fa02h   C050 Fc02h   C030 Fe02h   C010 Fg02h Cg00 R00hh"
{

getDimensions(width, height, channels, slices, frames);
fn=getTitle();

if (channels!=1){
	exit("Only works on a single channel or RGB image - try splitting channels");
}

run("Duplicate...", "duplicate");
rename("Shade");

title = "Method";
msg = "Only works on a single channel (z and or time) or RGB image \n  \n- enter a value for the sigma radius and using the PREVIEW \n- create a Gaussian blur that represents the background\n press OK to continue";
waitForUser(title, msg);

run("Gaussian Blur...");



if (slices!=1 || frames!=1){
	
LowPixelvalue=newArray(frames*slices);

setBatchMode(true);


for (slice=0;slice<slices;slice++){
	Stack.setSlice(slice);
for (frame=1;frame<=frames;frame++){
Stack.setFrame(frame);
run("Measure");
LowPixelvalue[slice*frames+frame-1]=getResult("Min", slice*frames+frame-1);
}
}
Array.getStatistics(LowPixelvalue, min, max, mean, stdDev);

selectWindow("Results");
run("Close");

selectWindow("Shade");
run("Subtract...", "value=min stack");

imageCalculator("Subtract create stack", fn,"Shade");
     
selectWindow("Shade");
run("Close");

selectWindow(fn);
run("Close");
setBatchMode("exit and display");
exit();
}

run("Measure");
LowPixelValue=getResult("Min", 0);
selectWindow("Results");
run("Close");

run("Subtract...", "value=LowPixelValue");
imageCalculator("Subtract create", fn,"Shade");
selectWindow("Shade");
run("Close");
selectWindow(fn);
run("Close");

}


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


macro "Shade correction (using Gaussian blur: multiply method) Action Tool - C0g0 F002h   C0e0 F202h   C0c0 F402h   C0a0 F602h   C090 F802h   C070 Fa02h   C050 Fc02h   C030 Fe02h   C010 Fg02h Cg00 R00hh Cggg T6e122"
{

getDimensions(width, height, channels, slices, frames);
fn=getTitle();

if (channels!=1){
	exit("Only works on a single channel or RGB image - try splitting channels");
}

title = "Method";
msg = "Only works on a single channel (z and or time) or RGB image \n  \n- enter a value for the sigma radius and using the PREVIEW \n- create a Gaussian blur that represents the background\n press OK to continue";
waitForUser(title, msg);



//stack ot time
if (slices!=1 || frames!=1){
	
MeanValue=newArray(frames*slices);

run("Duplicate...", "title=Shade duplicate");
run("Gaussian Blur...");

setBatchMode(true);

for (slice=0;slice<slices;slice++){
	Stack.setSlice(slice);
for (frame=1;frame<=frames;frame++){
Stack.setFrame(frame);
run("Measure");
MeanValue[slice*frames+frame-1]=getResult("Mean", slice*frames+frame-1);
}
}

selectWindow("Results");
run("Close");

selectWindow("Shade");
run("32-bit");

for (slice=0;slice<slices;slice++){
	Stack.setSlice(slice);
for (frame=1;frame<=frames;frame++){
Stack.setFrame(frame);
run("Divide...", "value="+MeanValue[slice*frames+frame-1]+" slice");
}
}

run("Reciprocal", "stack");
imageCalculator("Multiply create stack", fn,"Shade");
     
selectWindow("Shade");
run("Close");

setBatchMode("exit and display");
}else{



//single image
run("Duplicate...", "title=Shade");
run("Gaussian Blur...");
run("Measure");

MeanValue=getResult("Mean", 0);
selectWindow("Results");
run("Close");
selectWindow("Shade");
run("32-bit");
run("Divide...", "value=MeanValue");
run("Reciprocal");

imageCalculator("Multiply create", fn,"Shade");

selectWindow("Shade");
run("Close");
}

}

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

macro "Shade Correction Using a Reference Image Action Tool- C0g0 F002h C0e0 F202h C0c0 F402h C0a0 F602h C090 F802h C070 Fa02h C050 Fc02h C030 Fe02h C010 Fg02h Cg00 R00hh Cggg F24d9 C00g T4c08r T8c08e Tdc08f" {

//arrays
list=getList("image.titles");
method=newArray("Multiply","Add");
join="";
chns="";

//check if images exist
if (list.length<2){
	exit(""+list.length+" image open - This macro needs at Least 2 images");
}

//select images
Dialog.create("Options 1");
Dialog.addChoice("Image to be Corrected", list, list[0]);
Dialog.addChoice("Shade Correction Image", list,list[1]);
//Dialog.addChoice("Corretcion method", method, "Multiply");
Dialog.show();

fn=Dialog.getChoice();
shfn=Dialog.getChoice();


//check dimensions
selectWindow(fn);
getDimensions(Orig_width, Orig_height, Orig_channels, Orig_slices, Orig_frames);
selectWindow(shfn);
getDimensions(Sh_width, Sh_height, Sh_channels, Sh_slices, Sh_frames);

Adj=false;
if (Sh_width!=Orig_width || Sh_height!=Orig_height){
Adj=getBoolean("Shade and Original images are not the same X-Y dimensions", "Adjsut Shade image Dimensions", "Do Not Adjust");	
}
if (Adj==true){
	selectWindow(shfn);
run("Size...", "width=Orig_width height=Orig_height depth=1 average interpolation=Bilinear");
}


/////////////////corretion for single image
run("Select None");
CR="create";
IM=fn;
if (Orig_channels==Sh_channels){
	create_shade();
	equal_channels();
	rename(fn+" corrected");
	selectWindow("Shade");
	close();
}


///////////////corection for multi channel image
if (Orig_channels!=Sh_channels){
	Sh_Corr=newArray(Orig_channels);
//select channels to correct
Dialog.create("Options 2");
Dialog.addMessage("Image to be Corrected options");
for (ch=0;ch<Orig_channels;ch++){
	Dialog.addCheckbox("Correct Channel "+ch+1, true);
}
Dialog.show();
//get responses
for (ch=0;ch<Orig_channels;ch++){
	Sh_Corr[ch]=Dialog.getCheckbox();
}

//create shade
selectWindow(shfn);
create_shade();

//create corrected imges
CR="";
for (ch=0;ch<Orig_channels;ch++){
selectWindow(fn);
	run("Select None");
	run("Duplicate...", "title=[Ch_"+ch+1+"] duplicate channels="+ch+1);
	if (Sh_Corr[ch]==true){
		IM="Ch_"+ch+1;
		equal_channels();	
		chns=chns+" ch"+ch+1;
	}

join=join+"c"+ch+1+"=Ch_"+ch+1+" ";

}
selectWindow("Shade");
close();
//merge images
join=join+"create";
run("Merge Channels...", join);
rename(chns+" Corrected "+fn);
}

function create_shade() { 
selectWindow(shfn);
run("Select None");
run("Duplicate...", "title=Shade");
//create Shade correction image
run("Invert");
run("32-bit");
mn=getValue("Mean");
run("Divide...", "value=mn");
}

function equal_channels() { 
imageCalculator("Multiply "+CR+" stack", IM ,"Shade");	
}
}






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


macro "Select Channel Intensity Line Profile Plots(v2) Action Tool - C0g0 L1h43 L43hd C00g L1d6e L6eh4 Cg00 L1649 L49h8 Cg00 L1649 L49h8 C000 T3408l T6408i T9408n Tf408e L000h L0hhh Tdh082"
{
//plots an intensity profile of a multi channel image
//this version has auto LUT and plot size

run("Clear Results");

if (bitDepth()==24){
run("Make Composite");
}

setTool("line");

getDimensions(width, height, channels, slices, frames);


fn=getTitle();

getVoxelSize(px, py, pz, units);


bit=bitDepth();
yscalelim=pow(2, bit)-1;


getLine(x1, y1, x2, y2, lineWidth);

//select channels, line thickness, colour and transparency
Chans=newArray(channels);
colours = newArray("#4dff0000","#4d00ff00", "#4d0000ff","#4dff00ff","#4d00ffff","#4dffff00","#4dffc800","#4dffffff","#4d000000");

Dialog.create("Title")
  Dialog.addMessage("Analyse Channels");
  analyseChannel = newArray("Yes", "No");
  for (i=1; i<=channels; i++) {
  Ch="Channel " + i;
  Dialog.addRadioButtonGroup(Ch, analyseChannel, 1, 1, "Yes");
  }
  items = newArray("red","green","blue","magenta","cyan","yellow","orange","black","white");
  Dialog.addChoice("Line Colour", items, "green");
  opt = newArray("Yes","No");
  Dialog.addChoice("Line Semi-Transparent ?", opt, "Yes");
  Dialog.addNumber("Line width", lineWidth); 
Dialog.show(); 

for (w=1;w<=channels;w++){
Chans[w-1] = Dialog.getRadioButton();
}
Lcol=Dialog.getChoice();
transparent=Dialog.getChoice();
lnwdth=Dialog.getNumber();

if (lnwdth<1){
	lnwdth=1;
}

run("Line Width...", "line="+lnwdth);
run("Colors...", "selection="+Lcol);
colour=Lcol;
//get transparent colour 
if (transparent=="Yes"){
for (cl=0;cl<9;cl++){
	if (Lcol==items[cl]){
	colour=colours[cl];
}
}
}


//menu
Dialog.create("Plot size");
  Dialog.addMessage("Select Plot options: \n - if the colours appear wrong, you may need to re-set the LUT's\n - use the Change channel LUT's macro");
  range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
  Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
  Dialog.addNumber("Low intensity value ", 0, 0, 6," " );
  Dialog.addNumber("High intensity value ", yscalelim, 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("Set line width");
  Dialog.addNumber("Line width ", 1, 0, 4," pixels" );  
Dialog.show;

rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  


//draw line and get data
title = "Draw Profile";
msg = "Draw line \n \n then select OK to continue";
waitForUser(title, msg);

exist=selectionType();
if (exist==-1){
	exit("No selection - re-run macro");
}

Channel=getProfile();
xscalelen=lengthOf(Channel);


//get y range
highlevel=0;
lowlevel=yscalelim;
for (i=1;i<=channels;i++){
	if (Chans[i-1]=="Yes"){
if (channels>1){
Stack.setChannel(i);
}
Channel=getProfile();
Array.getStatistics(Channel, lowtemp, hightemp, mean, stdDev);

if (hightemp>highlevel){
	highlevel=hightemp;
}
if (lowtemp<lowlevel){
	lowlevel=lowtemp;
}
}
}
extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;


//get x range
	Distance=newArray(xscalelen);
for (g=0;g<xscalelen;g++){
	Distance[g]=g*px;
setResult("Distance (" + units +")", g, Distance[g]);
}


//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//main plot and results
        Plot.create(fn+" - Multi-Channel Intensity Plot", "Distance (" + units + ")", "Intensity");
        Plot.setLimits(0, xscalelen*px, ymin, ymax);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);
for (i=0;i<channels;i++){
	if (Chans[i]=="Yes"){
if (channels>1){
Stack.setChannel(i+1);
}
col=lookup();
Channel=getProfile();
name="Channel " + i+1;
for (row=0; row<lengthOf(Channel); row++)
{
setResult(name, row, Channel[row]);
}
		Plot.setColor(col);     
        Plot.add("line",Distance, Channel);
        Plot.addText("Channel " + i+1, i*0.1, 0);
}
}
Plot.show();

IJ.renameResults("Results",fn+" - Intensity Data");
//colour lookup

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;
}
}

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


macro "Select Channel Multiple line Intensity Profile Plots Action Tool - C0g0 L1h43 L43hd C00g L1d6e L6eh4 Cg00 L1649 L49h8 Cg00 L1649 L49h8 C000 T3408l T6408i T9408n Tf408e L000h L0hhh C000 T3g07R T9g07O Thg072"
{
//constants
colours = newArray("#4dff0000","#4d00ff00", "#4d0000ff","#4dff00ff","#4d00ffff","#4dffff00","#4dffc800","#4dffffff","#4d000000");
setTool("line");
lineWidth=1;
n=roiManager("count");

//file inf
fn=getTitle();

if (bitDepth()==24){
run("Make Composite");
}
getDimensions(width, height, channels, slices, frames);
Chans=newArray(channels);

if (slices>1 || frames>1){
	exit("This macro does not work on a Z or time series");
}

getVoxelSize(px, py, pz, units);

bit=bitDepth();
yscalelim=pow(2, bit)-1;



//get info
Dialog.create("Select Colour and Range");
	opt = newArray("Yes","No");
	if (n>0){
	Dialog.addChoice("Do you want to keep existing ROI's", opt, "Yes")
	}
	items = newArray("red","green","blue","magenta","cyan","yellow","orange","black","white");
	Dialog.addChoice("Colour", items, "green");
	Dialog.addChoice("Line Semi-Transparent ?", opt, "Yes")
	Dialog.addNumber("Line width", lineWidth);
	Dialog.addString("ROI Name", "Line", 12) 
	Dialog.addMessage("Analyse Channels");
	analyseChannel = newArray("Yes", "No");
	for (i=1; i<=channels; i++) {
	Ch="Channel " + i;
	Dialog.addRadioButtonGroup(Ch, analyseChannel, 1, 1, "Yes");
	}
Dialog.show();

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


col=Dialog.getChoice();
transparent=Dialog.getChoice();
lnwdth=Dialog.getNumber();
pre=Dialog.getString();
for (w=1;w<=channels;w++){
Chans[w-1] = Dialog.getRadioButton();

}

run("Line Width...", "line="+lnwdth);

colour=col;

//get transparent colour 
if (transparent=="Yes"){
for (b=0;b<9;b++){
	if (col==items[b]){
	colour=colours[b];
}
}
}

//draw line and get data
title = "Draw Profile";
msg = "Draw lines and add to ROI manager (t) \n \n then select OK to continue";
waitForUser(title, msg);

//rename Lines
n=roiManager("count");
if(n==0){
	exit("No ROI's")
	};

roiManager("deselect");
roiManager("Remove Channel Info");
roiManager("Remove Slice Info");
roiManager("Remove Frame Info");



//main routine
for (i=0; i<n; i++)
{
roiManager("select", i);
name=pre + " " + (i+1);
roiManager("Rename", name);
roiManager("Set Color", colour);
roiManager("Set Line Width", lnwdth);

}
roiManager("Deselect");
roiManager("Show all with labels");


//start of analysis

//plots an intensity profile of a multi channel image
//this version has auto LUT and plot size

run("Clear Results");


//menu
Dialog.create("Plot size");
  Dialog.addMessage("Select Plot options: \n - if the colours appear wrong, you may need to re-set the LUT's\n - use the Change channel LUT's macro");
  range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
  Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
  Dialog.addNumber("Low intensity value ", 0, 0, 6," " );
  Dialog.addNumber("High intensity value ", yscalelim, 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("Set line width");
  Dialog.addNumber("Line width ", 1, 0, 4," pixels" );
  op = newArray("Yes","No"); 
  Dialog.addChoice("Autosave Results ?", op, "No");
  Dialog.addChoice("Close all images automatically ?", op, "No");
Dialog.show;

rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  
sv=Dialog.getChoice();
clearall=Dialog.getChoice();

if (sv=="Yes"){
	output = getDirectory("Location for results");
}


for (R=0;R<n;R++){
selectWindow(fn);
roiManager("select", R);

Channel=getProfile();
xscalelen=lengthOf(Channel);


//get y range
highlevel=0;
lowlevel=yscalelim;
for (b=0;b<channels;b++){
	if (Chans[b]=="Yes"){
if (channels>1){
Stack.setChannel(b+1);
}
Channel=getProfile();
Array.getStatistics(Channel, lowtemp, hightemp, mean, stdDev);

if (hightemp>highlevel){
	highlevel=hightemp;
}
if (lowtemp<lowlevel){
	lowlevel=lowtemp;
}
}
}
extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;


//get x range
	Distance=newArray(xscalelen);
for (g=0;g<xscalelen;g++){
	Distance[g]=g*px;
setResult("Distance (" + units +")", g, Distance[g]);
}


//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//main plot and results
        Plot.create(fn+ " Intensity Plot Line "+R+1, "Distance (" + units + ")", "Intensity");
        Plot.setLimits(0, xscalelen*px, ymin, ymax);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);
for (i=0;i<channels;i++){
	if (Chans[i]=="Yes"){
if (channels>1){
Stack.setChannel(i+1);
}
col=lookup();
Channel=getProfile();
chname="Channel " + i+1 +" Line "+R+1;
for (row=0; row<lengthOf(Channel); row++)
{
setResult(chname, row, Channel[row]);
}
		Plot.setColor(col);     
        Plot.add("line",Distance, Channel);
        Plot.addText("Channel " + i+1, i*0.1, 0);
}
}
Plot.show();
if (sv=="Yes"){
out = output + fn + " Intensity Plot Line "+R+1;
saveAs("Jpeg", out);
}
}
IJ.renameResults("Results for "+fn);
if (sv=="Yes"){
out = output + fn + " results.xls";
saveAs("Results", out);

}
selectWindow(fn);
run("Stack to RGB");
roiManager("Show all with labels");
run("Flatten");
rename(fn+" overlay");
if (sv=="Yes"){
out = output + fn + " overlay";
saveAs("Jpeg", out);
roiManager("deselect");
roiManager("Save", output+fn+".zip");

if (clearall=="Yes" && sv=="Yes"){
selectWindow(fn + " results.xls");
run("Close");
run("Close All");
}
}

//colour lookup
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;
}
}

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

macro " Select Channel Intensity Line Profile Plots for Z stacks Action Tool - C0g0 L1h43 L43hd C00g L1d6e L6eh4 Cg00 L1649 L49h8 Cg00 L1649 L49h8 C4dd F58aa C000 T3408l T6408i T9408n Tf408e L000h L0hhh T7h10Z Tdh082"
{
//plots an intensity profile of a multi channel image
//this version has auto LUT and plot size

run("Clear Results");

if (bitDepth()==24){
run("Make Composite");
}

setTool("line");

getDimensions(width, height, channels, slices, frames);
fn=getTitle();

zfirst=1;
zlast=slices;

getVoxelSize(px, py, pz, units);

getLine(x1, y1, x2, y2, lineWidth);


//select channels, line thickness, colour and transparency
Chans=newArray(channels);
colours = newArray("#4dff0000","#4d00ff00", "#4d0000ff","#4dff00ff","#4d00ffff","#4dffff00","#4dffc800","#4dffffff","#4d000000");

Dialog.create("Title")
  Dialog.addMessage("Analyse Channels");
  analyseChannel = newArray("Yes", "No");
  for (i=1; i<=channels; i++) {
  Ch="Channel " + i;
  Dialog.addRadioButtonGroup(Ch, analyseChannel, 1, 1, "Yes");
  }
  items = newArray("red","green","blue","magenta","cyan","yellow","orange","black","white");
  Dialog.addChoice("Line Colour", items, "green");
  opt = newArray("Yes","No");
  Dialog.addChoice("Line Semi-Transparent ?", opt, "Yes");
  Dialog.addNumber("Line width", lineWidth); 
Dialog.show(); 

for (w=1;w<=channels;w++){
Chans[w-1] = Dialog.getRadioButton();
}
Lcol=Dialog.getChoice();
transparent=Dialog.getChoice();
lnwdth=Dialog.getNumber();

if (lnwdth<1){
	lnwdth=1;
}

run("Line Width...", "line="+lnwdth);
run("Colors...", "selection="+Lcol);
colour=Lcol;
//get transparent colour 
if (transparent=="Yes"){
for (cl=0;cl<9;cl++){
	if (Lcol==items[cl]){
	colour=colours[cl];
}
}
}


//get file info
getVoxelSize(px, py, pz, units);

bit=bitDepth();
yscalelim=pow(2, bit)-1;

Stack.getPosition(channel, zcurr, frame);


//menu
Dialog.create("Plot size");
  Dialog.addMessage("Select Plot options: \n - if the colours appear wrong, you may need to re-set the LUT's\n - use the Change channel LUT's macro");
  range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
  Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
  Dialog.addNumber("Low intensity value ", 0, 0, 6," " );
  Dialog.addNumber("High intensity value ", yscalelim, 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("Set line width");
  Dialog.addNumber("Line width ", 1, 0, 4," pixels" );
  Dialog.addMessage("For Z Stacks - select the Z Range \n");
  Dialog.addNumber("First Z Slice ", zfirst, 0, 5, "" ); 
  Dialog.addNumber("Last Z Slice ", zlast, 0, 5, "");
  Dialog.addCheckbox("Just Current Slice Z="+zcurr, 0);  
Dialog.show;

rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  
zfirst = Dialog.getNumber();
zlast = Dialog.getNumber();
SingleZ= Dialog.getCheckbox();

if (zlast>slices || zlast<zfirst || zfirst<1){
	exit("Z out of Range");
}

setBatchMode(true);

if (SingleZ==1){
	zfirst=zcurr;
	zlast=zcurr;
	setBatchMode(false);
}

//draw line and get data
title = "Draw Profile";
msg = "Draw line \n \n then select OK to continue";
waitForUser(title, msg);

exist=selectionType();
if (exist==-1){
	exit("No selection - re-run macro");
}

Channel=getProfile();
xscalelen=lengthOf(Channel);





//get y range
highlevel=0;
lowlevel=yscalelim;


for (zslice=zfirst;zslice<=zlast;zslice++){
Stack.setSlice(zslice); 

for (i=1;i<=channels;i++){
//selected channel
if (Chans[i-1]=="Yes"){

if (channels>1){
Stack.setChannel(i);
}


Channel=getProfile();
Array.getStatistics(Channel, lowtemp, hightemp, mean, stdDev);

if (hightemp>highlevel){
	highlevel=hightemp;
}
if (lowtemp<lowlevel){
	lowlevel=lowtemp;
}
}
}
}

extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;


//get x range
	Distance=newArray(xscalelen);
for (g=0;g<xscalelen;g++){
	Distance[g]=g*px;
setResult("Distance (" + units +")", g, Distance[g]);
}


//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//main plot and results

for (zslice=zfirst;zslice<=zlast;zslice++){ 
    selectImage(fn);
	Stack.setSlice(zslice);      
        
        Plot.create("Multi-Channel Intensity Plot", "Distance (" + units + ")", "Intensity");
        Plot.setLimits(0, xscalelen*px, ymin, ymax);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);
for (i=0;i<channels;i++){
//selected channel	
	if (Chans[i]=="Yes"){
if (channels>1){
Stack.setChannel(i+1);
}
col=lookupColour();
Channel=getProfile();
name="Channel " + i+1 + " Z="+ zslice;
for (row=0; row<lengthOf(Channel); row++)
{
setResult(name, row, Channel[row]);
}
		Plot.setColor(col);     
        Plot.add("line",Distance, Channel);
        Plot.addText("Channel " + i+1, i*0.1, 0);
        Plot.setFontSize(12);
        Plot.setColor("Black"); 
        Plot.addText("slice (" + zslice + ") Z=" + zslice*pz +" "+ units , 0.75, 0.07);
        Plot.setFontSize(12);
}
}
Plot.show();
rename("Plot of " + fn + " Z=" + zslice);
}

//join plots
if (zlast-zfirst>1){
join=" title=["+fn+" - Multichannel Plots] ";
n=1;
for (zslice=zfirst;zslice<=zlast;zslice++){
	join=join + " image"+n+"=[Plot of "+fn+" Z="+zslice+"]";
	n=n+1;
}

run("Concatenate...", join);

plot=1;
for (zslice=zfirst;zslice<=zlast;zslice++){
	Stack.setSlice(plot);
    setMetadata("Label", " Z Slice "+zslice+" ");
    plot=plot+1;
}

setBatchMode(false);

Stack.setSlice(1);
}

IJ.renameResults("Results",fn+" - Intensity Data");


//colour lookup function
function lookupColour(){
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;
}
}

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

macro " Select Channel Intensity Time Plots Action Tool - C0g0 L1h43 L43hd C00g L1d6e L6eh4 Cg00 L1649 L49h8 C000 T3408t T6408i T9408m Tg408e L000h L0hhh Tdh082"
{

//initialise
run("Clear Results");
setTool("oval");

//get file info
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);

//check data
if (ImageFrames==1 && ImageSlices==1){
	exit("This is not a time series");
}
if (ImageFrames>1 && ImageSlices>1){
	exit("This macro does not work on a Z stack time series");
}
if (ImageFrames==1 && ImageSlices!=1){
con=getBoolean("Image has only 1 frame, but " + ImageSlices + " slicess, do you want to convert slices to frames");
if (con==1){
run("Stack to Hyperstack...", "order=xyczt(default) channels=1 slices=" + ImageFrames + " frames=" + ImageSlices + " display=Color");	
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
Stack.setTUnit("frame");
}
}

//get bit depth
bit=bitDepth();
yscalelim=pow(2, bit)-1;

//select channels, colour 
Chans=newArray(ImageChannels);

Dialog.create("Title")
  Dialog.addMessage("Analyse Channels");
  analyseChannel = newArray("Yes", "No");
  for (i=1; i<=ImageChannels; i++) {
  Ch="Channel " + i;
  Dialog.addRadioButtonGroup(Ch, analyseChannel, 1, 1, "Yes");
  }
Dialog.show(); 
chansYes=0;
for (w=1;w<=ImageChannels;w++){
Chans[w-1] = Dialog.getRadioButton();
    if (Chans[w-1]=="yes"){
	chansYes=chansYes+1;
}
}

// create array
ChannelData=newArray(ImageFrames*ImageChannels);


//get plot details
Dialog.create("Plot size");
  Dialog.addMessage("Select Plot options: \n - if the colours appear wrong, you may need to re-set the LUT's\n - use the Change channel LUT's macro");
  range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
  Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
  Dialog.addNumber("Low intensity value ", 0, 0, 6," " );
  Dialog.addNumber("High intensity value ", yscalelim, 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("Set line width");
  Dialog.addNumber("Line width ", 1, 0, 4," pixels" );  
Dialog.show;

rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  
ymin=0;


//draw roi and print data
title = "Draw Profile";
msg = "Draw Roi\n \n then select OK to continue";
waitForUser(title, msg);
roiManager("Reset");
roiManager("Add");
roiManager("Multi Measure");

for (data=0;data<ImageFrames*ImageChannels;data++){
  ChannelData[data]=getResult("Mean1", data);
}

selectWindow("Results");
run("Close");



//get y range
highlevel=0;
lowlevel=yscalelim;
a=0;
for (clev=0;clev<ImageChannels;clev++){
if (Chans[clev]=="Yes"){

for (range=clev;range<(ImageFrames*ImageChannels);range+=ImageChannels){
	temprange=ChannelData[range];

	if 	(temprange>highlevel){
		highlevel=temprange;
	}
	if 	(temprange<lowlevel){
		lowlevel=temprange;
	}
}
}
}

extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;


//get x range
Frame_Interval=newArray(ImageFrames);
Fr=Stack.getFrameInterval();
if (Fr==0){
	Fr=1;
}
Stack.getUnits(X, Y, Z, Time, Value);
for (fi=1;fi<ImageFrames;fi++){
Frame_Interval[fi]=fi * Fr;
} 
Array.getStatistics(Frame_Interval, min, xscalelen, mean, stdDev);

for (t=0;t<ImageFrames;t++){
      setResult("Frame Interval (" + Time + ")", t, Frame_Interval[t]);
}


//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//main plot and results
Channel=newArray(ImageFrames);

        Plot.create(fn+" - Time Intensity Plot", "Time (" + Time + ")", "Intensity");
        Plot.setLimits(0, xscalelen, ymin, ymax);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);

for (k=0;k<ImageChannels;k++){
	if (Chans[k]=="Yes"){
if (ImageChannels>1){
Stack.setChannel(k+1);
}

for (j=0;j<ImageFrames;j++){
	  Channel[j]=ChannelData[j*ImageChannels+(k)];	
      name="Channel " + k+1;
      setResult(name, j, Channel[j]);
}
col=lookup();
		Plot.setColor(col);     
        Plot.add("line",Frame_Interval, Channel);
        Plot.addText("Channel " + k+1, k*0.1, 0);
}
}
Plot.show();

IJ.renameResults("Results",fn+" - Intensity Data");

// select colour

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;
}
}

}

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


macro "Multi Select Channel Intensity Line Profile for Time Series Action Tool - C0g0 L1h43 L43hd C00g L1d6e L6eh4 Cg00 L1649 L49h8 Cg00 L1649 L49h8 C000 T3308l T6308i T9308n Tf308e T3g08t T6g08i T8g08m Tgg08e T8a082 L000h L0hhh"
{
//plots an intensity line profile of a multi channel image time series with channel select
//this version has auto LUT and plot size

run("Clear Results");

if (bitDepth()==24){
run("Make Composite");
}

setTool("line");

getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
fn=getTitle();
Chans=newArray(ImageChannels);
getVoxelSize(px, py, pz, units);
bit=bitDepth();
yscalelim=pow(2, bit)-1;
Stack.getUnits(X, Y, Z, Time, Value);
Frame_Interval=newArray(ImageFrames);
FrIn=Stack.getFrameInterval();
for (fi=1;fi<ImageFrames;fi++){
Frame_Interval[fi]=fi * FrIn;
} 

if (ImageSlices>1){
	exit("This is a Z Stack image - this macro only works on a Time series");
}

getVoxelSize(px, py, pz, units);
bit=bitDepth();
yscalelim=pow(2, bit)-1;


//menu
Dialog.create("Plot size");
  Dialog.addMessage("Select Plot options: \n - if the colours appear wrong, you may need to re-set the LUT's\n - use the Change channel LUT's macro");
  range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
  Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
  Dialog.addNumber("Low intensity value ", 0, 0, 6," " );
  Dialog.addNumber("High intensity value ", yscalelim, 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("Set line width");
  Dialog.addNumber("Line width ", 1, 0, 4," pixels" );

  	analyseChannel = newArray("Yes", "No");
	for (i=1; i<=ImageChannels; i++) {
	Ch="Analyse Channel " + i;
	Dialog.addRadioButtonGroup(Ch, analyseChannel, 1, 2, "Yes");
	}
Dialog.show;

rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  
for (w=1;w<=ImageChannels;w++){
Chans[w-1] = Dialog.getRadioButton();
}





//draw line and get data
title = "Draw Line Profile";
msg = "Draw line\n \n then select OK to continue";
waitForUser(title, msg);

setBatchMode(true);

exist=selectionType();
if (exist==-1){
	exit("No selection - re-run macro");
}


//get y range
highlevel=0;
lowlevel=yscalelim;

for (Im=1;Im<=ImageFrames;Im++){
Stack.setFrame(Im);
for (ch=1;ch<=ImageChannels;ch++){
	if  (Chans[ch-1]=="Yes"){
		
Stack.setChannel(ch);	
Channel=getProfile();
Array.getStatistics(Channel, lowtemp, hightemp, mean, stdDev);

if (hightemp>highlevel){
	highlevel=hightemp;
}
if (lowtemp<lowlevel){
	lowlevel=lowtemp;
}
}
}
}

extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;

xscalelen=lengthOf(Channel);


//get x range
Distance=newArray(xscalelen);
for (g=0;g<xscalelen;g++){
	Distance[g]=g*px;
	setResult("Distance (" + units +")", g, Distance[g]);
}


//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//main plot and results
for (fr=1;fr<=ImageFrames;fr++){

//	Channel=getProfile();            
        Plot.create("Intensity Plot", "Distance (" + units + ")", "Intensity");
        Plot.setLimits(0, xscalelen*px, ymin, ymax);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);

for (ch=1;ch<=ImageChannels;ch++){
	if  (Chans[ch-1]=="Yes"){		
	selectImage(fn);
	Stack.setFrame(fr); 
	Stack.setChannel(ch);	
	Channel=getProfile();
	col=lookupColour();

	name="Chan: "+ch+" time pt="+ fr+ " (" +Frame_Interval[fr-1]+" "+Time+")";
for (row=0; row<lengthOf(Channel); row++){
setResult(name, row, Channel[row]);
}
		Plot.setColor(col);     
        Plot.add("line",Distance, Channel);
        Plot.setFontSize(12);
        Plot.setColor("Black"); 
        Plot.addText("frame (" + fr + ") T=" + Frame_Interval[fr-1] +" "+ Time , 0.75, 0.07);
	}
}
Plot.show();
rename("Plot of " + fn + " T=" + fr);
}


//join images
if (ImageFrames>1){
join=" title=["+fn+" - Series Time Plots] ";
n=1;
for (Im=1;Im<=ImageFrames;Im++){
	join=join + " image"+n+"=[Plot of " + fn + " T=" + Im +"]";
	n=n+1;
}

run("Concatenate...", join);

plot=1;
for (Im=1;Im<=ImageFrames;Im++){
	Stack.setSlice(plot);
    setMetadata("Label", " Time Point "+Im);
    plot=plot+1;
}
Stack.setSlice(1);
}
setBatchMode(false);



IJ.renameResults("Results",fn+" - Intensity Data");


//lookup colour
function lookupColour(){
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;
}
}


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

macro "Variable Time Series (meta title) Time Stamp/Intensity Plot multi ROIs (one channel) Action Tool - C0g0 L1h43 L43hd C0aa L1d6e L6eh4 Ca0a L1649 L49h8 C000 T3508V Ta508a Tf508r T2h08T T7h08i T9h08m Thh08e L000h L0hhh"
{

//initialize
fn=getTitle();
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
Stack.getUnits(X, Y, Z, Time, Value);
Int=Stack.getFrameInterval();
roiManager("reset");
LabelSize=ImageHeight/20;

Ttop=0;
Tbot=ImageHeight-LabelSize-10;
cols=newArray("White","Black","Red","Green","Blue","Magenta","Cyan","Yellow");


//dialog
Dialog.create("Options");
rw=newArray( "Save interval from image to a file", "Write interval from a file to image", "Plot Intensity Data","Write a constant interval to image");
Dialog.addRadioButtonGroup("Options:", rw, 4, 1, "Write a constant value to image");
Dialog.addNumber("Start value to write: ", 0);
Dialog.addNumber("Constant Interval value to write: ", Int);
Dialog.addString("Interval Units", Time);
Dialog.addMessage("Add Time Stamp on Image");
pos=newArray("None","Top Left","Bottom Left");
Dialog.addRadioButtonGroup("Position", pos, 1, 3, "None");
Dialog.addChoice("Label Colour", cols);
Dialog.addCheckbox("Flatten to image", false);
Dialog.show();

//response
option=Dialog.getRadioButton();
Start=Dialog.getNumber();
Int=Dialog.getNumber();
un=Dialog.getString();
Pr=Dialog.getRadioButton();
Label_colour=Dialog.getChoice();
fl=Dialog.getCheckbox();

//write interval to meta label on image
if (option=="Write a constant interval to image"){
for (Im=0;Im<ImageFrames;Im++){
Stack.setFrame(Im+1);
setMetadata("Label",(Int*Im)+Start);
}
}
// Stack.setTUnit(un);


//read and save interval from meta label to file
if (option=="Save interval from image to a file"){
Interval=newArray(ImageFrames);
Frame=newArray(ImageFrames);
for (Im=0;Im<ImageFrames;Im++){
Stack.setFrame(Im+1);
Frame[Im]="frame "+Im+1;
Interval[Im]=getMetadata("Label");
}
//Array.show("Interval "+fn,Frame,Interval);
Array.show(Frame,Interval);
IJ.renameResults("Arrays","Results");
saveAs("Results");
}


//read interval from file and write to meta label
if (option=="Write interval from a file to image"){
open("");
for (Im=0;Im<ImageFrames;Im++){
	Stack.setFrame(Im+1);
setMetadata("Label",getResult("Interval",Im));
}
}

///////////////////////////////////////////

if (option=="Plot Intensity Data"){

//constants
run("Clear Results");
setTool("oval");
n=roiManager("Count");
roiManager("Show All with labels");


if (ImageFrames==1){
	exit("This is not a time series");
}

//get bit depth
bit=bitDepth();
yscalelim=pow(2, bit);

//get plot details
Dialog.create("Plot Details");
	opt = newArray("Yes","No");
	if (n>0){
		Dialog.addChoice("Do you want to keep existing ROI's", opt, "Yes")
	}
    Dialog.addMessage("Select Plot options: \n ");
    range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
    Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
    Dialog.addNumber("Low intensity value ", 0, 0, 6," pixels" );
    Dialog.addNumber("High intensity value ", yscalelim, 0, 6," pixels" );
    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("Set line width");
    Dialog.addNumber("Line width ", 1, 0, 4," pixels" );  
Dialog.show;

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


rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  
ymin=0;


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


// create arrays
n=roiManager("count");
roiManager("deselect");
roiManager("Remove Channel Info");
roiManager("Remove Slice Info");
roiManager("Remove Frame Info");
RoiData=newArray(ImageFrames*n);
RoiPlot=newArray(ImageFrames);


//reame and colour and roi's
for (i=0;i<n;i++){
roiManager("select", i);
name="ROI " + i+1;
roiManager("Rename", name);
Col=ColourGen();
roiManager("Set Color", Col);
}
roiManager("Deselect");
roiManager("Multi Measure");

//setBatchMode("hide");

for (roi=0;roi<n;roi++){
for (j=0;j<ImageFrames;j++){	
  RoiData[j+(ImageFrames*roi)]=getResult("Mean(ROI "+roi+1+")", j);
} 
}
selectWindow("Results");
run("Close");

//get y range
Array.getStatistics(RoiData, lowlevel, highlevel, mean, stdDev);
extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;


//get x range
Frame_Interval=newArray(ImageFrames);
for (Im=0;Im<ImageFrames;Im++){
Stack.setFrame(Im+1);
Frame_Interval[Im]=getMetadata("Label");
}


Array.getStatistics(Frame_Interval, xmin, xscalelen, mean, stdDev);
for (t=0;t<ImageFrames;t++){
      setResult("Frame Interval (" + Time + ")", t, Frame_Interval[t]);
}



//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//create plots and results
Channel=newArray(ImageFrames);

for (m=0;m<n;m++){
for (p=0;p<ImageFrames;p++){
  	  RoiPlot[p]=RoiData[p+(ImageFrames*m)];	
      name="Roi " + m+1;
      setResult(name, p, RoiPlot[p]);
}
		Plot.create(fn+" - Time Intensity Plot ROI "+m+1, "Time (" + Time + ")", "Intensity");
        Plot.setLimits(xmin, xscalelen, ymin, ymax);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);
		
		roiManager("Select",m);
	 	PlotCol=Roi.getStrokeColor;
		Plot.setColor(PlotCol);     
        Plot.add("line",Frame_Interval, RoiPlot);
        Plot.show();
}


//join plots
if (n>1){
join=" title=["+fn+" - ROI Plots] ";
pl=1;
for (rplot=0;rplot<n;rplot++){
	join=join + " image"+pl+"=["+fn+" - Time Intensity Plot ROI "+rplot+1+"]";
	pl=pl+1;
}
run("Concatenate...", join);

//rename meta data
for (rplot=0;rplot<n;rplot++){
	Stack.setSlice(rplot+1);
    setMetadata("Label", fn+"  ROI "+rplot+1+"  ");
}

//project plots
selectWindow(fn+" - ROI Plots");
run("Z Project...", "projection=[Min Intensity]");
rename(fn+" All ROI Plot");

selectWindow(fn+" - ROI Plots");
Stack.setSlice(1);

//setBatchMode("exit and display");

//finish up
IJ.renameResults("Results",fn+" - Intensity Data");
selectWindow(fn);
roiManager("Show All with labels");

//randon=m colour generator
function ColourGen(){
Red=floor(random*255);
RedHex=toHex(Red);
Green=floor(random*255);
GreenHex=toHex(Green);
Blue=floor(random*255);
BlueHex=toHex(Blue);
RoiCol="#"+RedHex+GreenHex+BlueHex;
return RoiCol;
}
}
}







////////////////////////////////////////////

//print time on image
selectWindow(fn);
run("Colors...", "foreground=white background=black selection="+Label_colour);
setFont("SansSerif", LabelSize, "bold");
if (Pr=="Top Left"){
	p=Ttop;
}
if (Pr=="Bottom Left"){
	p=Tbot;
}

if (Pr!="None"){
for (Im=0;Im<ImageFrames;Im++){
Stack.setFrame(Im+1);
tt=getMetadata("Label");
makeText(tt+" "+un, 5, p);
roiManager("add");
}
if (fl==true){
lab=Array.getSequence(ImageFrames);
roiManager("Select", lab);
roiManager("Draw");
}	
}

}

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

macro " Profile plot in Z with Channel select Action Tool -  C00g L0141 L0444 L0747 L0a4a L0d4d L0g4g C000 L616g L60h0  C0g0 Ld1dg Cg00 L81fg Coog Lg19g"
{

run("Clear Results");

// Z profile plot
//get file info
getDimensions(width, height, channels, slices, frames);


fn=getTitle();


if (slices==1){
	exit("This is not a Z stack - use the time series");
}
if (frames!=1){
	exit("This is a time series - This maco only works on single time point z stack");
}


//setTool("oval");

//get bit depth
bit=bitDepth();
yscalelim=pow(2, bit)-1;


//select channels, colour 
Chans=newArray(channels);

Dialog.create("Title")
  Dialog.addMessage("Analyse Channels");
  analyseChannel = newArray("Yes", "No");
  for (i=1; i<=channels; i++) {
  Ch="Channel " + i;
  Dialog.addRadioButtonGroup(Ch, analyseChannel, 1, 1, "Yes");
  }
Dialog.show(); 
chansYes=0;
for (w=1;w<=channels;w++){
Chans[w-1] = Dialog.getRadioButton();
    if (Chans[w-1]=="yes"){
	chansYes=chansYes+1;
}
}

// create array
ChannelData=newArray(slices*channels);


//get plot details
Dialog.create("Plot size");
  Dialog.addMessage("Select Plot options: \n - if the colours appear wrong, you may need to re-set the LUT's\n - use the Change channel LUT's macro");
  range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
  Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
  Dialog.addNumber("Low intensity value ", 0, 0, 6," " );
  Dialog.addNumber("High intensity value ", yscalelim, 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("Set line width");
  Dialog.addNumber("Line width ", 1, 0, 4," pixels" );  
Dialog.show;

rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  
ymin=0;


//draw roi and measure
title = "Draw ROI";
msg = "Draw Roi\n \n then select OK to continue";
waitForUser(title, msg);
roiManager("Reset");
roiManager("Add");
roiManager("Multi Measure");

for (i=0;i<slices*channels;i++){

  ChannelData[i]=getResult("Mean1", i);
}

selectWindow("Results");
run("Close");



//get y range
highlevel=0;
lowlevel=yscalelim;
a=0;
for (clev=0;clev<channels;clev++){
if (Chans[clev]=="Yes"){

for (range=clev;range<(slices*channels);range+=3){
	temprange=ChannelData[range];

	if 	(temprange>highlevel){
		highlevel=temprange;
	}
	if 	(temprange<lowlevel){
		lowlevel=temprange;
	}
}
}
}

extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;


//get x range
Z_Interval=newArray(slices);
getVoxelSize(vx, vy, vz, units);
Stack.getUnits(X, Y, Zunits, Time, Value);



//Stack.getUnits(X, Y, Z, Time, Value);
for (Zint=0;Zint<slices;Zint++){
Z_Interval[Zint]=Zint * vz;
} 
//Array.getStatistics(Z_Interval, min, max, mean, stdDev);
//xscalelen=max;
for (t=0;t<slices;t++){
      setResult("Z Position",t , Z_Interval[t]);
}
Z_max=Z_Interval[slices-1];

//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//main plot and results
Channel=newArray(slices);

        Plot.create(fn+" - Z Profile Plot", "Z Position (" + Zunits + ")", "Intensity");
        Plot.setLimits(0, Z_max, ymin, ymax);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);

for (k=0;k<channels;k++){
	if (Chans[k]=="Yes"){
if (channels>1){
Stack.setChannel(k+1);
}



for (j=0;j<slices;j++){
	  Channel[j]=ChannelData[j*channels+(k)];	
      name="Channel " + k+1;
      setResult(name, j, Channel[j]);
}
col=lookup();
		Plot.setColor(col);     
        Plot.add("line",Z_Interval, Channel);
        Plot.addText("Channel " + k+1, k*0.1, 0);
}
}
Plot.show();

IJ.renameResults("Results",fn+" - Intensity Data");

// select colour

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;
}
}

}

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

macro "FWHM Intensity Sum of Line Profile  Action Tool - Cg0g H666hchc69300 C000 P0h3e597492b7efgh00 L000h L0hhh" 
{

//initialise
requires("1.52o");
run("Set Measurements...", "area mean min centroid median display redirect=None decimal=3");
run("Clear Results");
fn=getTitle();
run("Select None");
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
frameInterval=Stack.getFrameInterval();
Stack.getUnits(Xunit, Yunit, Zunit, Timeunit, LutValue);
if (ImageSlices>1 || ImageChannels>1){
	exit("This macro does not work on a z-stack or multichanel image");
}



//frame arrays
Baseline_Intensity=newArray(ImageFrames);
Corrected_Max_Intensity=newArray(ImageFrames);
FWHM_Intensity_Sum=newArray(ImageFrames);
FWHM_width=newArray(ImageFrames);
time=newArray(ImageFrames);
Frame=newArray(ImageFrames);

n=roiManager("count");

Yes_No=newArray("Yes","No");
Dialog.create("Options");
if (n>0){
Dialog.addChoice("Keep Existing Lines?", Yes_No);
}
Dialog.addChoice("Smooth Data?", Yes_No);
Dialog.show();

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


smooth_data=Dialog.getChoice();

//draw line
setTool("line");
waitForUser("Draw lines and press t to add to the ROI manager \n \n then press OK");
n=roiManager("count");
if (n<1){
	exit("No ROI's");
}
roiManager("deselect");
roiManager("Remove Channel Info");
roiManager("Remove Slice Info");
roiManager("Remove Frame Info");


if (ImageFrames==1){
// for single frame
S_Baseline_Intensity=newArray(n);
S_Corrected_Max_Intensity=newArray(n);
S_FWHM_Intensity_Sum=newArray(n);
S_FWHM_width=newArray(n);
S_line=newArray(n);
}



//main loop
for(roi=0;roi<n;roi++){
run("Clear Results");
selectWindow(fn);
roiManager("Select", roi);
roiManager("rename",roi+1);

//get graph limits
roiManager("Multi Measure");
run("Summarize");
if (ImageFrames==1){
	G_min=getResult("Min("+roi+1+")", 0)-getResult("Median("+roi+1+")", 0);
	G_max=getResult("Max("+roi+1+")", 0)-getResult("Median("+roi+1+")", 0)/2;	
}else{
G_min=getResult("Min("+roi+1+")", ImageFrames+3)-getResult("Median("+roi+1+")", ImageFrames+3);
G_max=getResult("Max("+roi+1+")", ImageFrames+3)-getResult("Median("+roi+1+")", ImageFrames+3)/2;
}
run("Clear Results");

//start process
setBatchMode(true);

for (fr=0;fr<ImageFrames;fr++){
time[fr]=fr*frameInterval;
Frame[fr]="Frame "+fr+1;	
selectWindow(fn);
if (ImageFrames>1){
Stack.setFrame(fr+1);
}
//get baseline (median)
roiManager("Select", roi);
run("Measure");
Baseline_Intensity[fr]=getResult("Median", fr);

//get profile and data
roiManager("Select", roi);
run("Plot Profile");
Plot.getValues(xpoints, ypoints);
close();

//correct for baseline
ln=ypoints.length;
ypoints_corrected=newArray(ln);
dist=Array.getSequence(ln);
for (data=0;data<ln;data++){
        pts = 1;
        tempvalue = ypoints[data];

//data smoothing
if (smooth_data=="Yes"){
       if (data>0){
            pts=pts+1;
            tempvalue=tempvalue+ypoints[data-1];
        }
        if (data<ln-1){
            pts=pts+1;
            tempvalue=tempvalue+ypoints[data+1];
        }
}     
	ypoints_corrected[data]=(tempvalue/pts)-Baseline_Intensity[fr];
	dist[data]=dist[data]*px;
}

//get max peak value
Array.getStatistics(ypoints_corrected, min, Corrected_Max_Intensity[fr], mean, stdDev);
Half_Max=Corrected_Max_Intensity[fr]/2;

//find max peak centre position
sortedValues = Array.copy(ypoints_corrected);
Array.sort(sortedValues);
MaxPos = Array.rankPositions(ypoints_corrected);
Max_centre=(MaxPos[ln-1]);


//find full width half max
PosLow=Max_centre;
PosHigh=Max_centre;
while (ypoints_corrected[PosLow]>=Half_Max && PosLow>0){
	PosLow=PosLow-1;
}
while (ypoints_corrected[PosHigh]>=Half_Max && PosHigh<ln-1){
	PosHigh=PosHigh+1;
}

//new FWHM array
fhg=newArray(ln);

//calculate area and width
FWHM_Intensity_Sum[fr]=0;
FWHM_width[fr]=0;
for (pos=PosLow+1;pos<PosHigh;pos++){
	FWHM_Intensity_Sum[fr]=FWHM_Intensity_Sum[fr]+ypoints_corrected[pos];
	FWHM_width[fr]=FWHM_width[fr]+1;
	fhg[pos]=ypoints_corrected[pos];
}
FWHM_width[fr]=FWHM_width[fr]*px;


// data arrays for single frame
if (ImageFrames==1){
S_FWHM_Intensity_Sum[roi]=FWHM_Intensity_Sum[fr];	
S_Corrected_Max_Intensity[roi]=Corrected_Max_Intensity[fr];	
S_Baseline_Intensity[roi]=Baseline_Intensity[fr];	
S_FWHM_width[roi]=FWHM_width[fr];
S_line[roi]="Line "+roi+1;
}


//plot profiles and FWHM
	Plot.create("Frame "+fr+1, "Distance "+unit, "Intensity");
	Plot.setFrameSize(500, 350);
	Plot.setColor("Blue", "Gray");
	Plot.add("line",dist,ypoints_corrected);
	Plot.setColor("Red", "Gray");
	Plot.add("bar",dist, fhg);
	Plot.setColor("Blue", "Gray");
	Plot.addText("Line: "+roi+1+"  Frame: "+fr+1+"  time: "+time[fr]+"  "+Timeunit, 0.03, 0.07);
	Plot.addText("FWHM Intensity Sum: "+FWHM_Intensity_Sum[fr], 0.03, 0.12);
	Plot.addText("FWHM Width: "+FWHM_width[fr]+ " "+unit, 0.6, 0.07);
	Plot.addText("Baseline Intensity: "+Baseline_Intensity[fr], 0.6, 0.12);
	Plot.setLimits(0, ln*px,G_min, G_max);
	Plot.show();

}

//display multiframe

if (ImageFrames>1){
run("Images to Stack", "name=["+fn+" Line "+roi+1+" Intensity plots] title=Frame use");
//Array.show(fn+" Line "+roi+1+" Measurements",Frame,time,Baseline_Intensity,Corrected_Max_Intensity,FWHM_width,FWHM_Intensity_Sum);
Table.create(fn+" Line "+roi+1+" Measurements");
Table.setLocationAndSize(25, 25, 800, 400);
Table.setColumn("Frame", Frame);
Table.setColumn("Time ("+Timeunit+")", time);
Table.setColumn("FWHM Intesity Sum", FWHM_Intensity_Sum);
Table.setColumn("FWHM Width ("+unit+")", FWHM_width);
Table.setColumn("Maximum Intesity (Corrected)", Corrected_Max_Intensity);
Table.setColumn("Baseline Intenity", Baseline_Intensity);
}
}


//display single frame
if (ImageFrames==1){
//Array.show(fn+" Measurements",S_line,S_Baseline_Intensity,S_Corrected_Max_Intensity,S_FWHM_width,S_FWHM_Intensity_Sum);
Table.create(fn+" Line "+roi+1+" Measurements");
Table.setLocationAndSize(25, 25, 700, 400);
Table.setColumn("Line", S_line);
Table.setColumn("FWHM Intesity Sum", S_FWHM_Intensity_Sum);
Table.setColumn("FWHM Width ("+unit+")", S_FWHM_width);
Table.setColumn("Maximum Intesity (Corrected)", S_Corrected_Max_Intensity);
Table.setColumn("Baseline Intenity", S_Baseline_Intensity);
run("Images to Stack", "name=["+fn+" Line "+roi+1+" Intensity plots] title=Frame use");
}

setBatchMode("exit and display");

//tidy up
selectWindow("Results");
run("Close");
setTool("rectangle");

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

}


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

macro "Time series line Re_Slice Profile analysis Action Tool - C555 F003f Cd55 F0432 P6c7c8b94a6b7c7d9e9faga C000 L636d L6dhd"
{
//creates a slice through time and pl0ts a profile

//initialise
run("Clear Results");
if (bitDepth()==24){
run("Make Composite");
}
//get image info
fn=getTitle();
bit=bitDepth();
yscalelim=pow(2, bit)-1;
getDimensions(ImageWidth, ImageHeight, ImageChannels, ImageSlices, ImageFrames);
getVoxelSize(px, py, pz, unit);
frameInterval=Stack.getFrameInterval();
Stack.getUnits(Xunit, Yunit, Zunit, Timeunit, LutValue);

//draw
setTool("line");
waitForUser("Draw Line","Draw line");
run("Reslice [/]...", "output=1.000 slice_count=1 avoid");
rename("profile");

getDimensions(ReSliceWidth, ReSliceHeight, ReSliceChannels, ReSliceSlices, ReSliceFrames);
Stack.setUnits(Xunit, Timeunit, Zunit, Timeunit, LutValue);
setVoxelSize(px, frameInterval, pz, unit);


LW=getNumber("Set Line Width", 1);
if (LW>ReSliceWidth){
	LW=ReSliceWidth;
}
run("Line Width...", "line=LW");
makeLine(ReSliceWidth/2, 0, ReSliceWidth/2, ReSliceHeight-1);


//menu
Dialog.create("Plot size");
  Dialog.addMessage("Select Plot options: \n - if the colours appear wrong, you may need to re-set the LUT's\n - use the Change channel LUT's macro");
  range = newArray(" Set own limits ", " Full intensity range ", " Limit to upper signal "," Limit to signal range ");
  Dialog.addRadioButtonGroup("Select intensity range (y-axis)", range, 1, 4, " Limit to signal range ");
  Dialog.addNumber("Low intensity value ", 0, 0, 6," " );
  Dialog.addNumber("High intensity value ", yscalelim, 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("Set line width");
  Dialog.addNumber("Line width ", 1, 0, 4," pixels" );  
Dialog.show;

rangelimits = Dialog.getRadioButton();
lowy = Dialog.getNumber(); 
highy = Dialog.getNumber(); 
plotsizex = Dialog.getNumber(); 
plotsizey = Dialog.getNumber();
plotlinewidth = Dialog.getNumber();  




exist=selectionType();
if (exist==-1){
	exit("No selection - re-run macro");
}

Channel=getProfile();
xscalelen=lengthOf(Channel);


//get y range
highlevel=0;
lowlevel=yscalelim;
for (i=1;i<=ImageChannels;i++){
if (ImageChannels>1){
Stack.setChannel(i);
}
Channel=getProfile();
Array.getStatistics(Channel, lowtemp, hightemp, mean, stdDev);


if (hightemp>highlevel){
	highlevel=hightemp;
}
if (lowtemp<lowlevel){
	lowlevel=lowtemp;
}
}
extend=(highlevel-lowlevel)*0.025;
highlevel=highlevel + extend;
lowlevel=lowlevel - extend;


//get x range
	Time=Array.getSequence(ImageFrames);
for (frame=0;frame<ImageFrames;frame++){
	Time[frame]=frame*frameInterval;
setResult("Time (" + Timeunit +")", frame, Time[frame]);
}


//y range selection
if (rangelimits==" Full intensity range "){
	ymax=yscalelim;
	ymin=0;
}
if (rangelimits==" Set own limits "){
	ymax=highy;
	ymin=lowy;
}
if (rangelimits==" Limit to upper signal "){
	ymax=highlevel;
	ymin=0;
}
if (rangelimits==" Limit to signal range "){
	ymin=lowlevel;
	ymax=highlevel;
}


//main plot and results
        Plot.create(fn+" - Multi-Channel Intensity Plot", "Time (" + Timeunit + ")", "Intensity");
        Plot.setLimits(0, ImageFrames*frameInterval, ymin, ymax);
        Plot.setFrameSize(plotsizex, plotsizey);
        Plot.setLineWidth(plotlinewidth);
for (ch=0;ch<ImageChannels;ch++){
if (ImageChannels>1){
Stack.setChannel(ch+1);
}
col=lookup();
Channel=getProfile();
name="Channel " + ch+1;
for (row=0; row<lengthOf(Channel); row++)
{
setResult(name, row, Channel[row]);
}
		Plot.setColor(col);     
        Plot.add("line",Time, Channel);
        Plot.addText("Channel " + ch+1, ch*0.1, 0);
}
Plot.show();

IJ.renameResults("Results",fn+" - Intensity Data");
run("Line Width...", "line=1");


//colour lookup
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;
}
}


