Compartmental models of growing neurites (Graham and van Ooyen 2004)

 Download zip file 
Help downloading and running models
Accession:59582
Simulator for models of neurite outgrowth. The principle model is a biophysical model of neurite outgrowth described in Graham and van Ooyen (2004). In the model, branching depends on the concentration of a branch-determining substance in each terminal segment. The substance is produced in the cell body and is transported by active transport and diffusion to the terminals. The model reveals that transport-limited effects may give rise to the same modulation of branching as indicated by the stochastic BESTL model. Different limitations arise if transport is dominated by active transport or by diffusion.
References:
1 . Graham BP, van Ooyen A (2004) Transport limited effects in a model of dendritic branching. J Theor Biol 230:421-32 [PubMed]
2 . Graham BP, van Ooyen A (2006) Mathematical modelling and numerical simulation of the morphological development of neurons. BMC Neurosci 7 Suppl 1:S9 [PubMed]
Model Information (Click on a link to find other models with that property)
Model Type: Axon; Dendrite;
Brain Region(s)/Organism:
Cell Type(s):
Channel(s):
Gap Junctions:
Receptor(s):
Gene(s):
Transmitter(s):
Simulation Environment: Java;
Model Concept(s): Development;
Implementer(s): Graham, Bruce [B.Graham at cs.stir.ac.uk];
/* Tree.java

Binary tree class
  - Trees consist of any number of objects of class Tree
  - Each object points to its parent (closer to root)
  - Each object may point to a left- and right-tree child
      - object is a continuation of a staight segment if
        ltree point to an object and rtree is null
      - object is a bifurcation point if both ltree and
        rtree point to tree objects.

BPG 4-3-03 time parameters changed to doubles
BPG 7-1-03 compiler errors fixed
BPG 6-6-00 intermediate path length calculation fixed
BPG 26-11-99 updated to use Graphics2D
BPG 28-9-99
*/

import java.awt.*;
import java.lang.Math;
import java.lang.Thread;
import java.io.*;


// Public generic binary tree class
public class Tree {

  // Public class variables
  public static int brkey;	// identifying branch key
                                // normally 1 + no.of branches

  // Public instance variables
  // Basic
  public String name;
  public Tree parent;
  public Tree ltree;
  public Tree rtree;
  public int key;  // identifying key
  public int order;  // centrifugal order
  public float length;  // length
  public float diam;  // diameter
  public float pathlength;  // path length to segment
  // Graphics
  public int locx;  // x-coord for screen drawing
  public int locy;  // y-coord for screen drawing
  // File IO
  public FileOutputStream fout;
  public PrintWriter pout;

  // Class variables for housekeeping and graphics
  public static int currx;  // current x position
  public static int curry;  // current y position
  public static float scalex;  // x-scaling (for drawing)
  public static int incx;  // increment in x per node (for printing)
  public static int incy;  // increment in y per node (for both)
  public static float bangle;  // branch angle (for real drawing)
  public static float badel;  // scale factor on branch angle
  public static long drawdel;  // delay between draw updates
  public static float maxLength;  // max possible path length
  public static float scsoma;  // scale factor for soma
  public static float scdend;  // scale factor for dendrite
  // File IO
  public static String tname;	// tree class name
  public static int fstore=0;  // flag to indicate "store data"


  // Basic tree constructors
  // More complex constructors are contained in subclasses

  // Constructor without parent node (root tree)
  public Tree() {
    key = 0;
    order = 0;
    parent = null;
    ltree = null;
    rtree = null;
  }


  // Constructor with parent node (subtree)
  public Tree(Tree parent) {
    this();  // basic constructor
    this.parent = parent;
  }


  // Constructor with parent node and identifying key and order
  public Tree(Tree parent, int key, int order) {
    this(parent);
    this.key = key;
    this.order = order;
  }


  // Constructor with parent node, key, order, length and diameter
  public Tree(Tree parent, int key, int order, float length, float diam) {
    this(parent, key, order);
    this.length = length;
    this.diam = diam;
  }



  // Tree housekeeping methods

  // Count segments in tree
  public int countSegments() {
    if (ltree == null && rtree == null)
      return 1;
    else if (rtree == null)
      return ltree.countSegments();
    else
      return 1 + ltree.countSegments() + rtree.countSegments();
  }


  // Count terminal nodes in tree
  public int countTerminals() {
    if (ltree == null && rtree == null)
      return 1;
    else if (rtree == null)
      return ltree.countTerminals();
    else
      return ltree.countTerminals() + rtree.countTerminals();
  }


  // Store terminal values (indexed by key)
  public void termValues(float[] termV, String pname) {
    if (parent == null)  // soma
      termV[key] = getValue(pname);
    if (ltree == null && rtree == null) {
      if (termV.length > key)
        termV[key] = getValue(pname);  // store terminal value
    };
    if (ltree != null) ltree.termValues(termV, pname);
    if (rtree != null) rtree.termValues(termV, pname);
 }


  // Calculate total path length in tree
  public float totPathLength() {
    if (parent == null) // soma not included
      return ltree.totPathLength();
    else if (ltree == null && rtree == null)
      return length;
    else if (rtree == null)
      return ltree.totPathLength() + length;
    else
      return length + ltree.totPathLength() + rtree.totPathLength();
  }


  // Find maximum path length in tree
  public float maxPathLength() {
    float lpath, rpath;

    if (parent == null)  // soma not included
      pathlength = 0;
//      pathlength = length;
    else
      pathlength = parent.pathlength + length;
    if (ltree == null && rtree == null) {
      return(pathlength);
    }
    else if (rtree == null)
      return ltree.maxPathLength();
    else {
      lpath = ltree.maxPathLength();
      rpath = rtree.maxPathLength();
    };
    if (lpath > rpath) return lpath;
    else return rpath;
  }


  // Store terminal path lengths
  public int termLengths(float[] termL, int i) {
    if (ltree == null && rtree == null) {
      termL[i] = length;  // store terminal length
      return i+1;
    }
    else if (rtree == null)
      return ltree.termLengths(termL, i);
    else
      return rtree.termLengths(termL, ltree.termLengths(termL, i));
  }


  // Store intermediate path lengths (NOT QUITE RIGHT)
  public int intLengths(float[] intL, int i) {
    if (ltree == null && rtree == null)
      return i;
    else if (ltree != null && rtree != null) {
      intL[i] = length;  // store intermediate length
      return rtree.intLengths(intL, ltree.intLengths(intL, i+1));
    }
    else if (ltree == null && rtree != null)
      return rtree.intLengths(intL, i);
    else
      return ltree.intLengths(intL, i);
  }


  // Store all path lengths
  public int pathLengths(float[] pathL, int i) {
    if (ltree == null && rtree == null) {
      pathL[i] = pathlength;  // store path length
      return i+1;
    }
    else if (ltree == null)
      return rtree.pathLengths(pathL, i);
    else if (rtree == null)
      return ltree.pathLengths(pathL, i);
    else
      return rtree.pathLengths(pathL, ltree.pathLengths(pathL, i));
  }


  // Store centrifugal orders
  public int centOrders(int[] centO, int i) {
    if (ltree == null && rtree == null) {
      centO[i] = order;  // store centrifugal order
      return i+1;
    }
    else if (rtree == null)
      return ltree.centOrders(centO, i);
    else
      return rtree.centOrders(centO, ltree.centOrders(centO, i));
  }


  // Find maximum centrifugal order in tree
  public int maxOrder() {
    if (ltree == null && rtree == null) {
      return order;  // terminal order
    }
    else if (rtree == null)
      return ltree.maxOrder();
    else return Math.max(ltree.maxOrder(), rtree.maxOrder());
  }


  // Calculate asymmetry partition of tree
  public float asymPart() {
    int nTerms, lnTerms, rnTerms;
    float currPart;

    lnTerms = 0;
    rnTerms = 0;
    nTerms = countTerminals();
    if (nTerms == 1) {
      return 0;
    }
    else if (rtree == null)  // continuation of branch
      return(ltree.asymPart());
    else {
      lnTerms = ltree.countTerminals();
      rnTerms = rtree.countTerminals();
    };
    if (lnTerms == 1 && rnTerms == 1)
      return 0;
    currPart = (float)Math.abs(lnTerms-rnTerms) / (float)(lnTerms+rnTerms-2);
    return(currPart + ltree.asymPart() + rtree.asymPart());
  }


  // Calculate asymmetry of tree
  public float asymIndex() {
    int nTerms;

    nTerms = countTerminals();
    if (nTerms == 1) {
      return 0;
    }
    else return(asymPart() / (float)(nTerms-1));
  }



  // Dummy routines for growing trees
  //   - must be defined by subclasses

  // Branch all terminal nodes
  public void branchTree(double t) {
  }

  // Grow terminal nodes
  public void elongateTree(double t) {
  }

  // Set segment diameters
  public void diamTree(double t) {
  }

  // Update previous values
  public void updateTree(double t) {
  }

  // Get variable value
  public float getValue(String vname) {
    return 0f;
  }

  // Get terminal parameter value
  public float termValue() {
    return 0f;
  }



  // Methods for displaying trees

  // Display colour tree with active parameter value
  public void displayTree(Graphics g, int x0, int y0, int dw, int dh, String pname, float pmaxval) {
    // (x0, y0) is the top left-hand corner of display area
    // dh, dw are the height and width of the display area

    // Display tree
    Tree.currx = x0;
    Tree.curry = y0 + (dh / 2);  // middle height
    Tree.scalex = (float)dw / maxLength;
    drawRealTree(g, bangle, pname, pmaxval);
    try {Thread.sleep(drawdel);} catch(InterruptedException eIE){};

  }


  // Draw tree as realistic branching structure in colour
  public void drawRealTree(Graphics g1, float bang, String pname, float pmval) {
    float dl, dh, dx, dy;
    float pval;

    Graphics2D g = (Graphics2D) g1;
    Stroke dendStroke;

    locx = currx;
    locy = curry;

    // soma
    if (parent == null) {
      dl = scsoma * scalex * length;
      dh = scsoma * scalex * diam;
      // Get parameter value and maximum value
      pval = getValue(pname);
      g.setColor(ColScale.ColVal(pval, pmval));
      g.fillOval(locx, locy-(int)(dh/2), (int)dl, (int)dh);
//      g.fillRect(locx, locy-(int)(dh/2), (int)dl, (int)dh);
//    g.drawLine(locx, locy, locx + (int)dl, locy);
      locx = currx + (int)dl;
      // set fixed line thickness for dendrites
//      dendStroke = new BasicStroke(scdend);
//      g.setStroke(dendStroke);
    };
    
    // draw continuing left tree
    if (ltree != null && rtree == null) {
      // dl = scalex * ltree.length;
      // dx = dl * (float)Math.cos((double)bangle*Math.PI/180);
      // dy = dl * (float)Math.sin((double)bangle*Math.PI/180);
      if (parent == null) {
        dx = scalex * ltree.length;
        dy = 0;
      } else {
        dx = (locx - parent.locx) * (ltree.length / length);
        dy = (locy - parent.locy) * (ltree.length / length);
      };
      currx = locx+(int)dx;
      curry = locy+(int)dy;
      // Get parameter value
      pval = ltree.getValue(pname);
      dendStroke = new BasicStroke(ltree.diam*scdend);
      g.setStroke(dendStroke);
      g.setColor(ColScale.ColVal(pval, pmval));
      g.drawLine(locx, locy, currx, curry);
      ltree.drawRealTree(g, bang, pname, pmval);
    }
    else {
    // draw left tree
    if (ltree != null) {
      dl = scalex * ltree.length;
      dx = dl * (float)Math.cos((double)bang*Math.PI/180);
      dy = dl * (float)Math.sin((double)bang*Math.PI/180);
      currx = locx+(int)Math.ceil((double)dx);
      curry = locy-(int)Math.ceil((double)dy);
      // Get parameter value
      pval = ltree.getValue(pname);
      dendStroke = new BasicStroke(ltree.diam*scdend);
      g.setStroke(dendStroke);
      g.setColor(ColScale.ColVal(pval, pmval));
      g.drawLine(locx, locy, currx, curry);
      ltree.drawRealTree(g, bang+(badel*bang), pname, pmval);
    };
    // draw right tree
    if (rtree != null) {
      dl = scalex * rtree.length;
      dx = dl * (float)Math.cos((double)bang*Math.PI/180);
      dy = dl * (float)Math.sin((double)bang*Math.PI/180);
      currx = locx+(int)Math.ceil((double)dx);
      curry = locy+(int)Math.ceil((double)dy);
      // Get parameter value
      pval = rtree.getValue(pname);
      dendStroke = new BasicStroke(rtree.diam*scdend);
      g.setStroke(dendStroke);
      g.setColor(ColScale.ColVal(pval, pmval));
      g.drawLine(locx, locy, currx, curry);
      rtree.drawRealTree(g, bang+(badel*bang), pname, pmval);
    };
    };

  }
  
  
  // Print tree to system output
  public void printTree() {
    System.out.println("Key: "+key+" Order: "+order);
    if (ltree != null) ltree.printTree();
    if (rtree != null) rtree.printTree();
  } 


  // Setup File IO for saving real-time segment data 
  public void setupFileIO() throws IOException {
    fout = new FileOutputStream(name+".pbr");
    pout = new PrintWriter(fout);
  }
  
  
  // Close output files
  public void closeFileIO() throws IOException {
    pout.close();
    if (ltree != null) ltree.closeFileIO();
    if (rtree != null) rtree.closeFileIO();
  }


}

Loading data, please wait...