/* TermPlot.java
Window (frame) for graph plots of terminal values.
Version 1.1 BPG 4-3-03 time parameters changed to doubles
Version 1.0 15-3-00 BPG
*/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class TermPlot extends Frame {
// Private instance variables
public PlotCanvas gp;
private Graphics g;
private String plot_data[][] = {
{"Plot width:", "300", "300"},
{"Plot height:", "150", "150"},
{"Plot parameter:", "Cbr", "Cbr"},
{"Maximum plot value:", "1.0", "1.0"},
{"Plot interval (steps):", "10", "10"},
{"Include soma (1=yes):", "0", "0"},
{"Save plot values (1=yes):", "0", "0"},
{"Save file stem:", "Br1", "Br1"}};
private final int Nplotd = 8;
private Color collist[] = {Color.black, Color.blue, Color.red,
Color.cyan, Color.green, Color.darkGray, Color.yellow,
Color.magenta, Color.gray, Color.orange, Color.pink,
Color.lightGray};
private int dispw=300; // display width
private int disph=150; // display height
private int dispoffx=10; // x offset
private int dispoffy=10; // y offset
private static final int maxfP=20;
private FileOutputStream[] fP;
private PrintWriter[] pP;
private int nTerms=0; // number of terminals
private float[] termV; // values in terminal nodes
// Public instance variables
public boolean refresh=true; // refresh display
public String ptitle;
public String pname=""; // parameter to plot
public float pmval=0.1f; // maximum plot value
public int dtplot=1; // time interval
public int somafl=0; // display soma value
public int sPflag=0; // store plot data flag
public String fPstem="test";
// Constructor
public TermPlot(String title, int width, int height, String pn, float mval, int dt, int sfl, int sflag, String fstem) {
// create frame
super(title);
// set parameter values
ptitle = title; // plot title
dispw = width; // plot width
disph = height; // plot height
pname = pn; // variable name
pmval = mval; // maximum data value
dtplot = dt; // refresh time interval
somafl = sfl; // include soma or not (1 or 0)
sPflag = sflag; // to store or not to store (1 or 0)
fPstem = fstem; // file stem for storage
// save parameter values in menu
plot_data[0][2] = String.valueOf(dispw);
plot_data[1][2] = String.valueOf(disph);
plot_data[2][2] = pname;
plot_data[3][2] = String.valueOf(pmval);
plot_data[4][2] = String.valueOf(dtplot);
plot_data[5][2] = String.valueOf(somafl);
plot_data[6][2] = String.valueOf(sPflag);
plot_data[7][2] = fPstem;
fP = new FileOutputStream[maxfP+1];
pP = new PrintWriter[maxfP+1];
// add menu bar
MenuItem item;
MenuBar mb = new MenuBar();
Menu wind = new Menu("Window", true);
mb.add(wind);
wind.add(item = new MenuItem("Close"));
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
Neurite.nplots--;
dispose();
}
});
wind.add(item = new MenuItem("Refresh"));
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
repaint();
}
});
Menu control = new Menu("Control", true);
mb.add(control);
control.add(item = new MenuItem("Params..."));
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
plotparams();
}
});
this.setMenuBar(mb);
// add canvas for drawing in
gp = new PlotCanvas(width, height);
this.add("Center", gp);
// allow closing
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
Neurite.nplots--;
dispose();
}
});
// set frame size and display
this.setResizable(true);
this.pack();
this.show();
g = this.getGraphics();
// draw graph;
refresh = true;
paint(g);
}
public void update(Graphics g) {
paint(g);
}
// Method for drawing graphs
public void paint(Graphics g) {
// check for resizing
Dimension currd = gp.getSize();
if (currd.width != dispw || currd.height != disph) {
dispw = currd.width;
disph = currd.height;
this.pack();
refresh = true;
};
if (refresh) {
// offscreen image for plot
gp.imagePlot = this.createImage(dispw, disph);
Graphics2D g2 = (Graphics2D) gp.imagePlot.getGraphics();
// axes for plotting
BasicStroke plotStroke = new BasicStroke(3.0f);
g2.setStroke(plotStroke);
g2.setColor(Color.blue);
g2.drawLine(dispoffx,disph-dispoffy,dispw-dispoffx,disph-dispoffy);
g2.drawLine(dispoffx,dispoffy,dispoffx,disph-dispoffy);
refresh = false;
};
gp.repaint();
}
// Window for user-setting of plot parameters
private void plotparams() {
DataEntry d = new DataEntry(new Frame(), "Plot Params", plot_data, Nplotd);
d.show();
dispw = Integer.parseInt(plot_data[0][2]);
disph = Integer.parseInt(plot_data[1][2]);
pname = plot_data[2][2];
this.setTitle(pname);
pmval = Float.valueOf(plot_data[3][2]).floatValue();
dtplot = Integer.parseInt(plot_data[4][2]);
somafl = Integer.parseInt(plot_data[5][2]);
sPflag = Integer.parseInt(plot_data[6][2]);
fPstem = plot_data[7][2];
}
// Plot terminal values
public void plotTerms(Graphics g, Tree br, double t, double Tstop, String pname, float maxv) {
int x, y, starti=1;
// get data
termV = new float[Tree.brkey];
for (int i=0; i < termV.length; i++) termV[i]=0;
br.termValues(termV, pname);
// plot data
x = dispoffx + (int)((dispw-(2*dispoffx))*t/Tstop);
if (somafl == 1) starti = 0; // include soma
for (int i=starti; i < Tree.brkey; i++) {
if (termV[i] > 0) {
y = disph - dispoffy - (int)((disph-(2*dispoffy))*termV[i]/maxv);
g.setColor(collist[i%collist.length]);
g.fillRect(x-1, y-1, 2, 2);
};
};
}
// Save terminal values
public void saveTerms(Tree br, double t, String pname) {
try {
// open new files, if necessary
if (Tree.brkey > nTerms && Tree.brkey <= maxfP) {
for (int i = nTerms; i < Tree.brkey; i++) {
fP[i] = new FileOutputStream(fPstem+"_"+i+"_"+pname+".dat");
pP[i] = new PrintWriter(fP[i]);
};
nTerms = Tree.brkey; // includes soma (key=0)
};
// get data
termV = new float[Tree.brkey];
for (int i=0; i < termV.length; i++) termV[i]=0;
br.termValues(termV, pname);
// save data
for (int i=0; i < Tree.brkey && i < maxfP; i++) { // incl. soma
pP[i].print(t);
pP[i].print(" ");
pP[i].println(termV[i]);
};
}
catch(IOException e){
System.out.println("I/O error has occurred");
System.exit(0);
};
}
// Flush terminal value files
public void flushTerms() {
int i = 0;
while (pP[i] != null) {
pP[i].flush();
pP[i].close();
i++;
};
nTerms = 0;
}
}
// Canvas to do plotting in
class PlotCanvas extends Canvas {
public Image imagePlot;
private int pcw, pch;
public PlotCanvas(int width, int height) {
super();
pcw = width;
pch = height;
this.setSize(pcw, pch);
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
g.drawImage(imagePlot,0,0,this);
this.getToolkit().sync(); // draw now
}
}