-
Notifications
You must be signed in to change notification settings - Fork 222
Proposal for morphologies
Morphology are used for simulation, access and plotting. For simulation, the geometry doesn't actually matter, only the electrical properties do. For access, the Morphology class is used to return the index of the compartment. Plotting should also be dealt with by the Morphology class.
I propose 1) to clearly separate properties that are relevant for simulation (i.e. electrically relevant) from others, 2) to make geometrical and electrical properties independent (ie not compute electrical properties from geometrical properties as is done currently), the relation being dealt with by the Morphology class, depending on specific implied geometry (eg truncated cone).
A morphology is a tree, each node being a branch. Each branch is a linear set of compartments, with junction points at the two ends (parent side / children side). For each compartment, properties are:
-
area (to calculate transmembrane currents)
-
volume (for diffusion)
-
curved length
-
resistive length (for axial currents)
-
x,y,z coordinates of electrical midpoint
Some explanations for the last two properties (4 and 5). Since the resistance depends on intracellular resistivity, which is only specified later, we instead calculate an effective length, that is, so that resistance is intracellular resistivity divided by effective length (for a cylinder, pi * d**2/4L). This gives a quantity that has units of meter, which we call the resistive length. Then, (x,y,z) coordinates correspond to the actual coordinates of all properties such as V, Im and others, i.e., the midpoint of the compartment. It makes sense (and is simpler) to choose the midpoint of the compartment as the point that splits the resistive length in two equal parts. For a cylinder, this would simply be the geometrical midpoint, but for a truncated cone, it would be biased towards the smaller end. This way, it is very easy to calculate the resistance between two successive compartments, which is just the average resistance of the two compartments. In the same way, the resistances at the two ends of the branch are just half-resistances of the corresponding compartments.
Curved length (3) is the geometrical length of the compartment, but not the Euclidian distance between the two end points. It is rather the total length along the possibly curved compartment. It is therefore decoupled from coordinates. This will make it easier for resegmenting a tree.
We may add, for convenience, a distance
properties, which is the distance from the origin of the branch to the midpoint (derived from curved length). This can be useful when setting channel properties (point to think about; we might rather want distance from the soma than from origin, for example). Alternatively, we could also have a position
property, which would indicate the distance relative to the total curved length (between 0 and 1). But in all cases, all properties that are state variables of the spatial neuron are meant at the electrical point.
All these properties above are considered independent. Diameter and end point coordinates are not core properties, but depend on the specific geometry (cylinder, truncated cone, sphere). The old 'distance' (in the previous version) is only used internally for access (i.e. to determine which compartment is meant when specifying a distance). We only need distance from branch origin, not from soma origin.
The properties should not be directly modifiable by the user; rather, set at construction time.
Note: I am just realizing that the electrical equivalent circuit at branches might be a bit inaccurate (to check; maybe not).
I propose the following two basic morphologies for branches:
- Isopotential sphere. This corresponds to the
Soma
class. It has zero resistive length but positive area. - Sequence of truncated cones. This is better than a sequence of cylinders for two reasons: it is more compatible with other tools and formats, and diameter is continuous (and so we don't have the problem of what to do with the surface at junctions). This implies that n+1 diameters are needed. A cylinder is a sequence of truncated cones and therefore can simply be a subclass.
I propose that the basic Morphology class does not have a specific geometry. This might reduce some confusions. Then:
- Branch derives from Morphology, and assumes a sequence of truncated cones.
- Cylinder derives from Branch (or from Morphology).
- Soma derives from Morphology, and is an isopotential single compartment. Spherical geometry is assumed.
- We may want to define a class derived from Branch for recompartmenting (merging compartments).
One issue is what to do with the surface at the two ends of a cylinder or truncated cones. Physically, those should be included in the calculation of area for the two compartments. However, as far as I know, no tool includes them. Furthermore, it is not obvious what to do at branching points. Therefore, I suggest to ignore it.
For the future, we should however give it a thought. Boundary surfaces could be included at construction, and then partially removed when branches are connected.
There are basically two ways of building morphologies: by loading a file, and by assembling blocks, mainly soma and truncated cones (or cylinders). In the current system, a morphology can be added as a child of another morphology, which means at the end of the main branch. This uses setattr
. For example: soma.axon = Cylinder(...)
. I propose to keep it this way for the moment. All these blocks have an origin (which may be implicitly specified by the coordinates and parameters).
When a block is built by giving its dimensions (eg diameter, length etc), the origin is by default zero. When it is inserted at the end of a morphology, the origin is shifted to ensure spatial continuity. This implies that all branches must have an endpoint (this is actually a bit tricky for the sphere and probably requires a special case). The angle is chosen either at random, or (better) by an algorithm.
In some cases, the soma is built up of several compartments. It is possible to do this in the current system, but one cannot attach branches (eg an axon and a dendrite) at two different ends of the soma. One needs to have e.g. a dendrite, of which the soma is a child, and the axon is a child of the soma. Then a dendrite is the root of the tree. It is also possible to do it more generally, with branches at midpoints of the soma, by breaking up the soma in pieces. It is of course not very elegant from the user side. I suggest to keep it this way for the moment. Later on, we might allow it with a specific syntax. It requires a new class where the main branch is a view on a set of branches.
The main problem we have is with the issue of multicompartmental soma mentioned above. There two options. Let us start with option 1.
Option 1: isopotential soma
We simply merge all compartments labeled as soma into a single isopotential soma of equivalent area, and make it the root of the tree.
Option 2: multibranch soma and views
We keep the tree structure, but the root is not the soma anymore but a dendrite. There is no object corresponding to the soma, which is split up across multiple branches. For convenience, a special compartment is designated as soma (say, the center of the soma). However, we lose easy access to the dendrites and axon (ie they are not children of the soma). To solve this, we could introduce a higher-order class that is sort of view on the morphology (e.g. one could write soma.axon and soma.dendrite even though axon and dendrite are not children of the soma). This mechanism would be used also for labeling different parts of the tree (e.g. the labels in SWC files and in Neurolucida files).
Resegmenting is not difficult in the context of general geometrical parameters (area, electric length), it is more challenging for coordinates. That is, to split a compartment in two, we might divide electric length, area etc by two (we should check what Neuron does). Coordinate interpolation is done independently (ie we do not enforce consistence).
I propose that resegmenting is done by producing a new Morphology object. We might want to keep a link to the original one for plotting (i.e. each compartment in the new morphology maps to a subbranch in the old morphology). In that case, simulation is done on the new morphology, but the compartments are mapped to old one for plotting.