# NeuroMaC examples¶

This section provides examples highlighting the key features of NeuroMac and illustrate how to use the software suite.

All examples are found in the examples directory. Bash shell scripts are available to run the models and convert the raw output into useful output (such as a SWC-file or figure). Check these shell scripts for individual commands.

Note

## Random walk¶

Not truly a random walk. Rather, several branches grow from the soma, start of straight before orientating themselves randomly. Consequently, the branches do not grow for long as they will inevitably bump into one another. The resultant structural overlaps are detected by NeuroMac and cause the branches to terminate.

### Run code¶

Run the example by executing the prepared bash script

$cd examples # Or from wherever you came. From now I assume you're in the examples directory$ ./run_random_walk.sh


This script (as well as all further example scripts) will do several things:

1. Run the model. Running the model generates a SQL database containing all generated structures.
2. Generate one SWC-file of the produced structure
3. Generate a movie of the development of the structure.
4. Generate two plots of the produced structure with and without radii, respectively.

The following files will be produced:

random_walk.db # raw SQL database
cell_type_1__0.swc  # SWC file
random_walk.mp4 # movie
random_walk_wire.pdf  # wire plot


### Implementation details¶

The user has to write two files: a configuration file and a file containing the growth cones. The configuration file (random_walk/random_walk.cfg) defines properties of the brain volume to simulate as well as which structures to grow in accordance to a specified set of rules. Also, the configuration file contains some parameters for NeuroMaC itself (see Configuration file).

Of most interest is the file containing the growth-rules:

random_walk/Random_machine.py

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from growth_procs import unit_sample_on_sphere,\ normalize_length,\ prepare_next_front L_NORM = 3.0 def extend_front(front,seed,constellation) : if front.order == 0: new_fronts = [] for i in range(5): rnd_dir = unit_sample_on_sphere() new_pos = normalize_length(rnd_dir,L_NORM*5) new_pos = front.xyz + new_pos new_front = prepare_next_front(front,new_pos,set_radius=1.0,add_order=True) new_fronts.append(new_front) return new_fronts else: rnd_dir = unit_sample_on_sphere() new_pos = normalize_length(rnd_dir,L_NORM) new_pos = front.xyz + new_pos new_front = prepare_next_front(front,new_pos,set_radius=1.0) return [new_front] 

In the first three lines several helper functions are imported. These come with NeuroMac (Front implementation helper functions). In short, the unit_sample_on_sphere is used to sample a 3D vector used as the component for random growth. normalize_length is used to scale a vector to the desired length while prepare_next_front is a secure wrapper to extend a front (If the work “front” does not ring a bell, please consult the NeuroMaC Rationale)

The actual growth-rule is described in extend_front(front,seed,constellation). Always include this exact method definition or NeuroMaC will not work!

In this case two separate rules are included. Two is the unofficial default: one rule describes the behaviour at the soma (or any other initial point with front.order==0) while the other rules covers the rest. Here five initial branches are started. Afterwards a front elongates with purely random angles.

• rnd_dir = unit_sample_on_sphere(): Get a unit length random 3D vector.
• new_pos = normalize_length(rnd_dir,L_NORM*5): Scale a vector to a length of L_NORM*5.

Warning

extend_front() always has to return a list of fronts. If only a single front is returned (as happens for elongations), return a list: return [new_front]. See Front growth-rule specification

## Attraction between fronts¶

Basic example illustrating phenomenological attraction between two developing neurites. One neurite structure simply grows straight while the second neurite is attracted by the first one.

In addition, this example illustrates how to parallelize the execution by decomposing the volume.

Code can be run by executing the following wrapper-command:



### Substrate configuration¶

To register the point cloud in the simulated volume, add it in the substrate section of the config file as illustrated below.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [system] seed=21051982 proxy_sub_port= 5599 proxy_pub_port= 5560 pull_port=55002 time_out = 10000 no_cycles=80 out_db=straight_to_pia/straight.db synapse_distance = 5 [substrate] dim_xyz = [100.0,100.0,200.0] pia = straight_to_pia/new_pia_points.pkl [sub_volumes] xa=1 ya=1 za=1 [cell_type_1] no_seeds=1 algorithm = Straight location = [[50,50,10],[50,50,10]] soma_radius = 10 

### Implementation details¶

The growth-rules are very similar to the rules required to implement attraction between neurites. The sole difference is that a list of “pia” entities is queried from the substrate.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import numpy as np from growth_procs import direction_to,\ normalize_length,\ get_entity,\ prepare_next_front L_NORM=3 def extend_front(front,seed,constellation) : """ Growth is directed by an attraction to the "pia"; a point-cloud \ located at the top of the volume. (See straight.cfg) """ other_entities = get_entity("pia",constellation) dir_to_entity = direction_to(front,other_entities,what="nearest") dir_to_entity = dir_to_entity new_pos = front.xyz + normalize_length(dir_to_entity,L_NORM) new_front = prepare_next_front(front,new_pos,set_radius=1.0) return [new_front] 

## Fronts updating the substrate¶

This example illustrates how a front can update the substrate by leaving an cue. This cue can be picked up by another front (or by the front itself; but that would be pointless) in the usual way.

Code can be run by executing the following wrapper-command:

\$ ./run_update_env.sh


### Configuration file¶

The configuration file contains no special instructions.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [system] seed=21051982 proxy_sub_port= 5599 proxy_pub_port= 5560 pull_port=55002 time_out = 10000 no_cycles=75 out_db=update_environment/update.db [substrate] dim_xyz = [100.0,100.0,100.0] [sub_volumes] xa=1 ya=1 za=1 [cell_type_1] no_seeds=1 algorithm = Update_env_machine location = [[80,50,50],[80,50,50]] soma_radius = 10 [cell_type_2] no_seeds=1 algorithm = Attracted_by location = [[40,10,10],[40,10,10]] soma_radius = 10 

### Front implementation¶

One front drops a series of cues at a specific moment. For demonstration purposes this moment is expressed in terms of update steps (a attribute of front.Front).

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import numpy as np from growth_procs import prepare_next_front L_NORM = 5 def extend_front(front,seed,constellation) : new_pos =front.xyz + np.array([-1.0*L_NORM,0,0]) new_front = prepare_next_front(front,new_pos,set_radius=3.0) # secrete some "substance_x" at some point if front.path_length > 40 and front.path_length < 46 : # special syntax for updating the environent return [new_front],{"substance_x":front} else : return [new_front] 

The other neurite can try to sense this substance. However, as long as the cue is not available, the neurite should catch the case that growth_procs.get_entity() returns an empty list, which cannot be passed to the growth_procs.direction_to() function.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import numpy as np from growth_procs import unit_sample_on_sphere,\ direction_to,\ normalize_length,\ get_entity,\ prepare_next_front L_NORM=2.0 def extend_front(front,seed,constellation) : # attract by a different neuron, get information other_entities = get_entity("substance_x",constellation) # fetch the case that no such entities exists if len(other_entities) == 0 : new_pos =front.xyz + np.array([L_NORM,0,0]) else : rnd_dir = unit_sample_on_sphere() dir_to_entity = direction_to(front,other_entities,what="nearest") dir_to_entity = normalize_length(dir_to_entity,1.0) + rnd_dir*0.3 new_pos = front.xyz + normalize_length(dir_to_entity,L_NORM) new_front = prepare_next_front(front,new_pos,set_radius=1.5) return [new_front] 

## Miscellaneous examples¶

### Forests of neurons¶

NeuroMac offers the opportunity to generate large numbers of neurites that may or may not have the same growth-rules. In this example, we grow a forest of neurons according to the same growth rules.

This can be specified in the configuration file [here to_pia/many.cfg]:

[cell_type_proto_purk1]
no_seeds=10
algorithm = Meander_to_pia
location = [[20,20,20],[180,180,20]]


### Built-in structural conflict detection¶

./run_intersection.sh

### Self-avoidance¶

./run_selfavoidance.sh

Distance-dependent attraction