Tutorial 7 — Your own rules, stages and models
The toolbox is extended through registries. Your code lives in your package (a plugin); projects and modules list the plugin, and it is imported whenever they are loaded.
A developmental rule
Rules modify the fixed growth procedure in five phases: placement, shift, target, probability, weight.
# my_project/rules.py
import numpy as np
from neurogenesis.development import register
@register("weight", "saturating_receptor")
def saturating_receptor(ctx):
"""gd["w_max"]: receptors saturate; weights above w_max are compressed."""
if "w_max" in ctx.gd: # inactive unless its gene is present
m = ctx.gd["w_max"]
ctx.w = np.sign(ctx.w) * m * np.tanh(np.abs(ctx.w) / m)
plan = BodyPlan(..., plugins=["my_project.rules"])
plan.rules["weight"] += ("saturating_receptor",)
genome["guidance"][("a", "b")]["w_max"] = 300.0
Rules must (1) act only when their genes are present, (2) draw no random numbers, (3) be listed in the plan. The built-in rules are listed in Extending neurogenesis-sim and building module projects.
A developmental stage
# my_project/stages.py
import numpy as np
from neurogenesis.stages.base import register_stage
from neurogenesis.params import Const, resolve
@register_stage("shrink")
class Shrink:
"""Scales positions towards the origin by `factor` (1 = no change)."""
def run(self, tissue, params, genome, fields, rng):
f = resolve(params.get("factor", Const(1.0)), genome, fields, tissue.positions)
tissue.positions = tissue.positions * f
return tissue
@staticmethod
def cost(N, E, params):
return 3 * 8 * N, 3 * N # bytes, operations
A stage must: read every parameter through a Param, use only the rng it is given, be a no-op with neutral
parameters, declare its cost, and come with a test on a toy tissue (see AGENTS.md).
A neuron model
Register a module with name, description, substeps, state_bytes, flops, init_state(net, seed) and
tick(net, state, ext), using models.base.drivers and models.base.transmit so that drivers and delays behave as
in every other model:
from neurogenesis.spiking.models import register_model
import my_project.izhikevich as izh
register_model(izh)
Details: Neuron models and their cost.
A geometry or field type
from neurogenesis.geometry import register_geometry
from neurogenesis.geometry.primitives import Geometry
@register_geometry("torus")
class Torus(Geometry):
... # contains, sample, bounding_box, local_coordinates, to_dict, from_dict
PLACEHOLDER
A cookiecutter template for a plugin / module repository (package layout, tests, CI, docs) and a community index of published plugins.