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

IO for network object

Open jasmainak opened this issue 3 years ago • 3 comments

@ntolley mentioned here that we don't have a way to save network objects. Since this is also a GSoC issue, I decided to make a quick prototype with hdf5:

from h5io import write_hdf5

from hnn_core import jones_2009_model
from hnn_core.network_models import add_erp_drives_to_jones_model

net = jones_2009_model()
add_erp_drives_to_jones_model(net)

cell_objs = dict()
for cell_type, cell in net.cell_types.items():
    cell_objs[cell_type] = dict()
    cell_objs[cell_type]['topology'] = cell.topology
    cell_objs[cell_type]['synapses'] = cell.synapses
    cell_objs[cell_type]['sections'] = dict()
    for sec_name, section in cell.sections.items():

        # XXX: partial func cannot be written
        mechs = dict()
        for mech_name, mech in section.mechs.items():
            mechs[mech_name] = dict()
            for mech_prop, prop_val in mech.items():
                if isinstance(prop_val, float):
                    mechs[mech_name][mech_prop] = prop_val

        # mechs = {k: v for (k, v) in section.mechs.items() if v}
        cell_objs[cell_type]['sections'][sec_name] = {
            'L': section.L,
            'diam': section.diam,
            'Ra': section.Ra,
            'cm': section.cm,
            'mechs': mechs,
            'syns': section.syns,
            'end_pts': section.end_pts
        }

for conn in net.connectivity:
    conn['gid_pairs'] = {str(k): v for (k, v) in conn['gid_pairs'].items()}

# XXX: writing net.connectivity is super slow
net_write = {'cells': cell_objs, 'external_drives': net.external_drives,
             'connectivity': net.connectivity}

write_hdf5('test.h5', net_write, overwrite=True)

related issues: https://github.com/jonescompneurolab/hnn-core/issues/170 https://github.com/jonescompneurolab/hnn-core/issues/341

jasmainak avatar Feb 18 '22 23:02 jasmainak

Anyone up for prototyping a NeuroML version of this to see what it would take and to identify what are the potential roadblocks? One would need to use the XML library in Python to do this.

jasmainak avatar Feb 18 '22 23:02 jasmainak

@jasmainak I think this could work as a NeuroML version to save network objects. However, in case of a complex network, with many cells and synapses, the file could possibly get very large. Accessing and altering or reading the data within the file may cause system slowdowns or slow response times maybe.


import xml.etree.ElementTree as ET

from hnn_core import jones_2009_model
from hnn_core.network_models import add_erp_drives_to_jones_model

net = jones_2009_model()
add_erp_drives_to_jones_model(net)

net_el = ET.Element('network')
cells_el = ET.SubElement(net_el, 'cells')

for cell_type, cell in net.cell_types.items():
    cell_el = ET.SubElement(cells_el, 'cell')
    cell_el.set('type', cell_type)
    
    topology_el = ET.SubElement(cell_el, 'topology')
    topology_el.text = cell.topology
    
    synapses_el = ET.SubElement(cell_el, 'synapses')
    synapses_el.text = cell.synapses
    
    sections_el = ET.SubElement(cell_el, 'sections')
    for sec_name, section in cell.sections.items():
        section_el = ET.SubElement(sections_el, 'section')
        section_el.set('name', sec_name)
        
        L_el = ET.SubElement(section_el, 'L')
        L_el.text = str(section.L)
        
        diam_el = ET.SubElement(section_el, 'diam')
        diam_el.text = str(section.diam)
        
        Ra_el = ET.SubElement(section_el, 'Ra')
        Ra_el.text = str(section.Ra)
        
        cm_el = ET.SubElement(section_el, 'cm')
        cm_el.text = str(section.cm)
        
        mechs_el = ET.SubElement(section_el, 'mechs')
        for mech_name, mech in section.mechs.items():
            mech_el = ET.SubElement(mechs_el, 'mech')
            mech_el.set('name', mech_name)
            
            for mech_prop, prop_val in mech.items():
                if isinstance(prop_val, float):
                    prop_el = ET.SubElement(mech_el, 'property')
                    prop_el.set('name', mech_prop)
                    prop_el.text = str(prop_val)
        
        syns_el = ET.SubElement(section_el, 'syns')
        syns_el.text = section.syns
        
        end_pts_el = ET.SubElement(section_el, 'end_pts')
        end_pts_el.text = section.end_pts

ex_drives_el = ET.SubElement(net_el, 'external_drives')
for ext_drive in net.external_drives:
    drive_el = ET.SubElement(ex_drives_el, 'drive')
    drive_el.set('name', ext_drive['name'])
    drive_el.set('type', ext_drive['type'])
    for drive_prop, prop_val in ext_drive.items():
        if drive_prop not in ('name', 'type'):
            prop_el = ET.SubElement(drive_el, 'property')
            prop_el.set('name', drive_prop)
            prop_el.text = str(prop_val)

# create connectivity element
connectivity_el = ET.SubElement(net_el, 'connectivity')
for conn in net.connectivity:
    conn_el = ET.SubElement(connectivity_el, 'connection')
    conn_el.set('src_gids', ','.join(str(gid) for gid in conn['src_gids']))
    conn_el.set('tgt_gids', ','.join(str(gid) for gid in conn['tgt_gids']))
    for conn_prop, prop_val in conn.items():
        if conn_prop not in ('src_gids', 'tgt_gids'):
            prop_el = ET.SubElement(conn_el, 'property')
            prop_el.set('name', conn_prop)
            prop_el.text = str(prop_val)

# write XML tree to file
with open('test.nml', 'w') as f

AryaItkyal avatar Apr 03 '23 18:04 AryaItkyal

@AryaItkyal I see you translated my code into XML which is a great starting point!

However what is really needed is to figure out how to map these objects to the Neuroml schema instead of a generic XML file. The output file must pass the validator

jasmainak avatar Apr 03 '23 21:04 jasmainak

Closed by #763

ntolley avatar Jul 31 '24 19:07 ntolley