next up previous
Next: An entity can construct Up: The Neosim interface [ Previous: Extracting data with derived

Populations

Large scale network models often include populations of similar entities. Neosim allows models to be defined at this high level, in terms of populations of cells and projections between populations. Having a high level model description also simplifies efficient implementation on parallel machines.

Example populations could be a layer of one type of neuron in a cortex, or a nucleus of similar cells. ``Views'' of populations can also be created, and treated as new populations; an example could select all cells over a certain size, or in a restricted region. Populations are treated as a special type of shared entity, which allows rapid lookup of elements of the population. Another example population could be a ``GeometryView'' which provides rapid lookup of all entities in a given region of space, an essential optimisation for setting up distance based connections in a large model.

In order to define a population, a modeller provides a name, an entity class, the number of elements, and a function to initialise each entity of the population.

Every entity is member of a Population , and there is a hierarchical naming structure for populations. There are methods to lookup an entity or population given a fully qualified name (e.g. "Cortex/layer3/pyramidal12345"):

EntityHandle lookupEntity( Time t, String name )
Population   lookupPopulation( Time t, String name )

A time argument is specified, as populations can change over time, with entities added and deleted. For the script reader, this argument will be the simulation time; for entities it will be the entity's local simulation time.

The population tree structure is available:

PopulationTree getPopulationTree( Time t )
It has methods for adding and removing population nodes from the tree, and for navigating the branches.


  
Figure 4: Example population tree.
\begin{figure}
\leavevmode \centering
\epsfxsize=4in

\epsffile {figs/poptree.eps}\end{figure}

A basic Population has a few methods:

String         getName()
PopulationNode getParent()
int            getId()
int            getNumEnts()
int            getIndex( EntityID eid )
boolean        isMember( Entity e )
Vector         getMemberList()      // Vector of all EntityIDs
void           construct()          // Build the population.

A PopulationBuilder extends the basic Population to include methods to instantiate a number of entities of a given class:

PopulationBuilder( EntityClass, int num, EntityInit ei )
EntityInit is a function to initialise entity i of the population.
interface EntityInit { void init( Entity e, Population p, int index); }
This can contain entity method calls to set the position, initial potentials, etc etc depending on the index in the population. Examples could include:
class InitMesh2D implements EntityInit {
  InitMesh2D( xsz, ysz, x1, y1, xspc, yspc );
  void init( Entity e, Population p, int index ) {
    e.setPos( index % xsz, index \ xsz );
  }
}

Views of a population can be constructed from an existing population:

  PopulationView( Population srcpop )
  final void addEntityToView( Entity e ); 
  void buildView( Entity e )
by overriding the buildView() method which is called for each entity in the source population.

An example population view is a selection based on pattern matching of the name:

  class RegexpMatch extends PopulationView {
    RegexpMatch( Population p, String regexp );
    void buildView( Entity e ) {
      if (regexp_match( regexp, e.getName() ) {
        addEntityToView( e ); 
      }
    }
  }

Population views can be used to provide rapid lookup of entities, e.g. a GridDecompositionView which puts entities into grid boxes. This can speed up specification of distance-based connection patterns as connection requests can be sent to nearby entities rather than all entities.

  class GridDecompositionView extends PopulationView {
    GridDecompositionView(double gridxsz, double gridysz, double zsz);
    Vector getMemberList( int gridx, int gridy, int gridz );
    void addEntityToView( Entity e, int x, int y, int z ) //...
    void buildView( Entity e ) {
      Pos p = e.getPos();
      int gridx = (int) p.getX() / gridxsz;
      int gridy = (int) p.getY() / gridysz;
      int gridz = (int) p.getZ() / gridzsz;
      addEntityToView( e, gridx, gridy, gridz );
    }
  }


  
Figure 5: Population view.
\begin{figure}
\leavevmode \centering
\epsfxsize=4in

\epsffile {figs/popview.eps}\end{figure}



 
next up previous
Next: An entity can construct Up: The Neosim interface [ Previous: Extracting data with derived
Fred Howell
8/15/1999