hnn-core icon indicating copy to clipboard operation
hnn-core copied to clipboard

separating the geometry of cells/networks from the Neuron code

Open jasmainak opened this issue 4 years ago • 1 comments

This has come up a few times in different contexts, most notably for the Network class. The reason one would want to separate the geometry from the actual Neuron code are:

  • it allows easy pickling of the class, necessary in the context of parallelization
  • it prevents weird bugs due to the way Neuron works. Neuron holds everything in global workspace. It's better to hold the state of objects in Python as much as possible and not in HOC.
  • it will allow HNN-core to be easily extensible to new kinds of neuron morphologies and networks
  • it is also more future proof. If there are updates to Neuron code, we can look in specific designated spots and update the code there. If there is another differential solver engine that we want to use for running our code, it will be straightforward to switch back and forth between Neuron and the others

This came up during our discussion with @blakecaldwell and @rythorpe

I tried to come up with a prototype here. This is literally from 3 hours of hacking, so nothing is final but gives an idea what we can aspire for. I would propose a Section, Cell and Network class, each with its own plot method and create or build_in_neuron method.

This 200 line script demos how one could load an arbitrary cell morphology downloaded from the internet and incorporate it in HNN workflow.

Screen Shot 2020-08-31 at 5 30 46 PM

I propose we start from cell.py first since network.py is still undergoing a few changes.

jasmainak avatar Aug 31 '20 21:08 jasmainak

I think this is pretty much done after #322 . One thing that remains is we could write readers for different types of morphology files:

def load_morphology(fname):
    from neuron import h
    h.xopen(fname)

    p_secs = dict()
    for sec in h.allsec():
        sec_name = sec.name()
        p_secs[sec_name] = dict()
        p_secs[sec_name]['diam'] = getattr(sec, 'diam', None)
        p_secs[sec_name]['L'] = getattr(sec, 'L', None)
        p_secs[sec_name]['Ra'] = getattr(sec, 'Ra', None)
        p_secs[sec_name]['cm'] = getattr(sec, 'cm', None)
        pts = list()
        for idx in range(sec.n3d()):
            pts.append([sec.x3d(idx), sec.y3d(idx), sec.z3d(idx)])
        p_secs[sec_name]['pts'] = pts

    cell = Cell(pos=(0., 0., 0.))
    cell.p_secs = p_secs
    return cell

Then the API would be so that you can do something like this:

import os.path as op

from hnn_core import load_morphology

url = 'http://cns.iaf.cnrs-gif.fr/files/CELLS/pyramidal264L.geo'
fname = 'pyramidal264L.geo'

if not op.exists(fname):
    urlretrieve(url, fname)

custom_cell = load_morphology(fname)

# inside network builder
cell.build()

I think it should be fairly straightforward to read the following formats with this machinery: asc, swc, xml, and hoc/geo:

h.Import3d_Neurolucida3()
h.Import3d_SWC_read()
h.Import3d_MorphML()

jasmainak avatar May 09 '21 16:05 jasmainak

Closed by #661 and #481

ntolley avatar Jul 10 '24 20:07 ntolley