def generate_granule_cell_layer(network_id, x_size = 0, # um y_size = 0, # um z_size = 0, # um numCells_grc = 0, numCells_gol = 0, connections = True, connections_method = 'random', connection_probability_grc_gol = 0.2, connection_probability_gol_grc = 0.1, inputs = False, input_firing_rate = 50, # Hz num_inputs_per_grc = 4, validate = True, random_seed = 1234, generate_lems_simulation = False, max_plotted_cells_per_pop = 10, duration = 500, # ms dt = 0.025, temperature="32.0 degC"): seed(random_seed) nml_doc = NeuroMLDocument(id=network_id) net = Network(id = network_id, type = "networkWithTemperature", temperature = temperature) net.notes = "Network generated using libNeuroML v%s"%__version__ nml_doc.networks.append(net) # The names of the cell type/component used in the populations (Cell Type in neuroConstruct) grc_group_component = "Granule_98" gol_group_component = "Golgi_98" nml_doc.includes.append(IncludeType(href='%s.cell.nml'%grc_group_component)) nml_doc.includes.append(IncludeType(href='%s.cell.nml'%gol_group_component)) # The names of the Exc & Inh groups/populations (Cell Group in neuroConstruct) grc_group = "Grans" gol_group = "Golgis" # The names of the network connections net_conn_grc_gol = "NetConn_Grans_Golgis" net_conn_gol_grc = "NetConn_Golgis_Grans" # The names of the synapse types (should match names at Cell Mechanism/Network tabs in neuroConstruct) grc_gol_syn = "AMPA_GranGol" gol_grc_syn = "GABAA" for syn in [grc_gol_syn, gol_grc_syn]: nml_doc.includes.append(IncludeType(href='%s.synapse.nml'%syn)) if network_id == 'Solinas2010': # Set size and cell numbers for Solinas 2010 network import sys,os NEURON_sim_path = '../NEURON' sys.path.append(NEURON_sim_path) local_path = os.getcwd() os.chdir(NEURON_sim_path) print os.getcwd() import GenerateSolinas2010 as GS2010 structure = GS2010.GenerateSolinas2010(generate=True) os.chdir(local_path) goc_data = structure['Golgis'] grc_data = structure['Granules'] grc_pos = grc_data['positions']['data'] goc_pos = goc_data['positions']['data'] numCells_grc = grc_pos.shape[0] numCells_gol = goc_pos.shape[0] # Generate excitatory cells grc_pop = Population(id=grc_group, component=grc_group_component, type="populationList", size=numCells_grc) net.populations.append(grc_pop) for i in range(0, numCells_grc) : index = i inst = Instance(id=index) grc_pop.instances.append(inst) inst.location = Location(x=str(grc_pos[i,0]), y=str(grc_pos[i,1]), z=str(grc_pos[i,2])) # Generate inhibitory cells gol_pop = Population(id=gol_group, component=gol_group_component, type="populationList", size=numCells_gol) net.populations.append(gol_pop) for i in range(0, numCells_gol) : index = i inst = Instance(id=index) gol_pop.instances.append(inst) inst.location = Location(x=str(goc_pos[i,0]), y=str(goc_pos[i,1]), z=str(goc_pos[i,2])) if connections: proj_grc_gol = Projection(id=net_conn_grc_gol, presynaptic_population=grc_group, postsynaptic_population=gol_group, synapse=grc_gol_syn) net.projections.append(proj_grc_gol) proj_gol_grc = Projection(id=net_conn_gol_grc, presynaptic_population=gol_group, postsynaptic_population=grc_group, synapse=gol_grc_syn) net.projections.append(proj_gol_grc) count_grc_gol = 0 count_gol_grc = 0 # Generate exc -> * connections def add_connection(projection, id, pre_pop, pre_component, pre_cell_id, pre_seg_id, post_pop, post_component, post_cell_id, post_seg_id): connection = Connection(id=id, \ pre_cell_id="../%s/%i/%s"%(pre_pop, pre_cell_id, pre_component), \ pre_segment_id=pre_seg_id, \ pre_fraction_along=0.5, post_cell_id="../%s/%i/%s"%(post_pop, post_cell_id, post_component), \ post_segment_id=post_seg_id, post_fraction_along=0.5) projection.connections.append(connection) # Connect Granule cells to Golgi cells for i in range(0, numCells_grc): # get targets for grc[i] from the structure dict # print 'Granule ', i , structure['Granules']['divergence_to_goc']['data'][i][1:] for j in structure['Granules']['divergence_to_goc']['data'][i][1:]: add_connection(proj_grc_gol, count_grc_gol, grc_group, grc_group_component, i, 0, gol_group, gol_group_component, j, 0) count_grc_gol+=1 # Connect Golgi cells to Granule cells for i in range(0, numCells_gol): # get targets glomeruli for goc[i] from the lol in structure dict # print 'Golgi ', i # print structure['Golgis']['divergence_to_glom']['data'][i][1:] for k in structure['Golgis']['divergence_to_glom']['data'][i][1:]: # get target granule cells for glom[k] from the lol in structure dict # print 'Glom ', k # print structure['Glomeruli']['divergence_to_grc']['data'][k] for j in structure['Glomeruli']['divergence_to_grc']['data'][k][1:]: # print 'Granule ', j add_connection(proj_gol_grc, count_gol_grc, gol_group, gol_group_component, i, 0, grc_group, grc_group_component, j, 0) count_gol_grc+=1 if inputs: mf_input_syn = "MF_AMPA" nml_doc.includes.append(IncludeType(href='%s.synapse.nml'%mf_input_syn)) rand_spiker_id = "input50Hz" #<poissonFiringSynapse id="Input_8" averageRate="50.0 per_s" synapse="MFSpikeSyn" spikeTarget="./MFSpikeSyn"/> pfs = PoissonFiringSynapse(id="input50Hz", average_rate="%s per_s"%input_firing_rate, synapse=mf_input_syn, spike_target="./%s"%mf_input_syn) nml_doc.poisson_firing_synapses.append(pfs) input_list = InputList(id="Input_0", component=rand_spiker_id, populations=grc_group) count = 0 for i in range(0, numCells_grc): for j in range(num_inputs_per_grc): input = Input(id=count, target="../%s/%i/%s"%(grc_group, i, grc_group_component), destination="synapses") input_list.input.append(input) count += 1 net.input_lists.append(input_list) ####### Write to file ###### print("Saving to file...") nml_file = network_id+'.net.nml' writers.NeuroMLWriter.write(nml_doc, nml_file) print("Written network file to: "+nml_file) if validate: ###### Validate the NeuroML ###### from neuroml.utils import validate_neuroml2 validate_neuroml2(nml_file) if generate_lems_simulation: # Create a LEMSSimulation to manage creation of LEMS file ls = LEMSSimulation("Sim_%s"%network_id, duration, dt) # Point to network as target of simulation ls.assign_simulation_target(net.id) # Include generated/existing NeuroML2 files ls.include_neuroml2_file('%s.cell.nml'%grc_group_component) ls.include_neuroml2_file('%s.cell.nml'%gol_group_component) ls.include_neuroml2_file(nml_file) # Specify Displays and Output Files disp_grc = "display_grc" ls.create_display(disp_grc, "Voltages Granule cells", "-95", "-38") of_grc = 'Volts_file_grc' ls.create_output_file(of_grc, "v_grc.dat") disp_gol = "display_gol" ls.create_display(disp_gol, "Voltages Golgi cells", "-95", "-38") of_gol = 'Volts_file_gol' ls.create_output_file(of_gol, "v_gol.dat") for i in range(min(numCells_grc,max_plotted_cells_per_pop)): quantity = "%s/%i/%s/v"%(grc_group, i, grc_group_component) ls.add_line_to_display(disp_grc, "GrC %i: Vm"%i, quantity, "1mV", pynml.get_next_hex_color()) ls.add_column_to_output_file(of_grc, "v_%i"%i, quantity) for i in range(min(numCells_gol,max_plotted_cells_per_pop)): quantity = "%s/%i/%s/v"%(gol_group, i, gol_group_component) ls.add_line_to_display(disp_gol, "Golgi %i: Vm"%i, quantity, "1mV", pynml.get_next_hex_color()) ls.add_column_to_output_file(of_gol, "v_%i"%i, quantity) # Save to LEMS XML file lems_file_name = ls.save_to_file() print "-----------------------------------"
def generate_example_network(network_id, numCells_exc, numCells_inh, x_size = 1000, y_size = 100, z_size = 1000, exc_group_component = "SimpleIaF", inh_group_component = "SimpleIaF_inh", validate = True, random_seed = 1234, generate_lems_simulation = False, connections = True, connection_probability_exc_exc = 0.4, connection_probability_inh_exc = 0.4, connection_probability_exc_inh = 0.4, connection_probability_inh_inh = 0.4, inputs = False, input_firing_rate = 50, # Hz input_offset_min = 0, # nA input_offset_max = 0, # nA num_inputs_per_exc = 4, duration = 500, # ms dt = 0.05, temperature="32.0 degC"): seed(random_seed) nml_doc = NeuroMLDocument(id=network_id) net = Network(id = network_id, type = "networkWithTemperature", temperature = temperature) net.notes = "Network generated using libNeuroML v%s"%__version__ nml_doc.networks.append(net) for cell_comp in set([exc_group_component, inh_group_component]): # removes duplicates nml_doc.includes.append(IncludeType(href='%s.cell.nml'%cell_comp)) # The names of the Exc & Inh groups/populations exc_group = "Exc" inh_group = "Inh" # The names of the network connections net_conn_exc_inh = "NetConn_Exc_Inh" net_conn_inh_exc = "NetConn_Inh_Exc" net_conn_exc_exc = "NetConn_Exc_Exc" net_conn_inh_inh = "NetConn_Inh_Inh" # The names of the synapse types (should match names at Cell Mechanism/Network tabs in neuroConstruct) exc_inh_syn = "AMPAR" inh_exc_syn = "GABAA" exc_exc_syn = "AMPAR" inh_inh_syn = "GABAA" for syn in [exc_inh_syn, inh_exc_syn]: nml_doc.includes.append(IncludeType(href='%s.synapse.nml'%syn)) # Generate excitatory cells exc_pop = Population(id=exc_group, component=exc_group_component, type="populationList", size=numCells_exc) net.populations.append(exc_pop) for i in range(0, numCells_exc) : index = i inst = Instance(id=index) exc_pop.instances.append(inst) inst.location = Location(x=str(x_size*random()), y=str(y_size*random()), z=str(z_size*random())) # Generate inhibitory cells inh_pop = Population(id=inh_group, component=inh_group_component, type="populationList", size=numCells_inh) net.populations.append(inh_pop) for i in range(0, numCells_inh) : index = i inst = Instance(id=index) inh_pop.instances.append(inst) inst.location = Location(x=str(x_size*random()), y=str(y_size*random()), z=str(z_size*random())) if connections: proj_exc_exc = Projection(id=net_conn_exc_exc, presynaptic_population=exc_group, postsynaptic_population=exc_group, synapse=exc_exc_syn) net.projections.append(proj_exc_exc) proj_exc_inh = Projection(id=net_conn_exc_inh, presynaptic_population=exc_group, postsynaptic_population=inh_group, synapse=exc_inh_syn) net.projections.append(proj_exc_inh) proj_inh_exc = Projection(id=net_conn_inh_exc, presynaptic_population=inh_group, postsynaptic_population=exc_group, synapse=inh_exc_syn) net.projections.append(proj_inh_exc) proj_inh_inh = Projection(id=net_conn_inh_inh, presynaptic_population=inh_group, postsynaptic_population=inh_group, synapse=inh_inh_syn) net.projections.append(proj_inh_inh) count_exc_inh = 0 count_inh_exc = 0 count_exc_exc = 0 count_inh_inh = 0 for i in range(0, numCells_exc): for j in range(0, numCells_inh): if i != j: if random()<connection_probability_exc_inh: add_connection(proj_exc_inh, count_exc_inh, exc_group, exc_group_component, i, 0, inh_group, inh_group_component, j, 0) count_exc_inh+=1 if random()<connection_probability_inh_exc: add_connection(proj_inh_exc, count_inh_exc, inh_group, inh_group_component, j, 0, exc_group, exc_group_component, i, 0) count_inh_exc+=1 for i in range(0, numCells_exc): for j in range(0, numCells_exc): if i != j: if random()<connection_probability_exc_exc: add_connection(proj_exc_exc, count_exc_exc, exc_group, exc_group_component, i, 0, exc_group, exc_group_component, j, 0) count_exc_exc+=1 for i in range(0, numCells_inh): for j in range(0, numCells_inh): if i != j: if random()<connection_probability_inh_inh: add_connection(proj_inh_inh, count_inh_inh, inh_group, inh_group_component, j, 0, inh_group, inh_group_component, i, 0) count_inh_inh+=1 if inputs: if input_firing_rate>0: mf_input_syn = "AMPAR" if mf_input_syn!=exc_inh_syn and mf_input_syn!=inh_exc_syn: nml_doc.includes.append(IncludeType(href='%s.synapse.nml'%mf_input_syn)) rand_spiker_id = "input_%sHz"%input_firing_rate pfs = PoissonFiringSynapse(id=rand_spiker_id, average_rate="%s per_s"%input_firing_rate, synapse=mf_input_syn, spike_target="./%s"%mf_input_syn) nml_doc.poisson_firing_synapses.append(pfs) input_list = InputList(id="Input_0", component=rand_spiker_id, populations=exc_group) count = 0 for i in range(0, numCells_exc): for j in range(num_inputs_per_exc): input = Input(id=count, target="../%s/%i/%s"%(exc_group, i, exc_group_component), destination="synapses") input_list.input.append(input) count += 1 net.input_lists.append(input_list) if input_offset_max != 0 or input_offset_min != 0: for i in range(0, numCells_exc): pg = PulseGenerator(id="PulseGenerator_%i"%i, delay="0ms", duration="%sms"%duration, amplitude="%fnA"%(input_offset_min+(input_offset_max-input_offset_min)*random())) nml_doc.pulse_generators.append(pg) input_list = InputList(id="Input_Pulse_List_%i"%i, component=pg.id, populations=exc_group) input = Input(id=0, target="../%s/%i/%s"%(exc_group, i, exc_group_component), destination="synapses") input_list.input.append(input) net.input_lists.append(input_list) ####### Write to file ###### print("Saving to file...") nml_file = network_id+'.net.nml' writers.NeuroMLWriter.write(nml_doc, nml_file) print("Written network file to: "+nml_file) if validate: ###### Validate the NeuroML ###### from neuroml.utils import validate_neuroml2 validate_neuroml2(nml_file) if generate_lems_simulation: # Create a LEMSSimulation to manage creation of LEMS file ls = LEMSSimulation("Sim_%s"%network_id, duration, dt) # Point to network as target of simulation ls.assign_simulation_target(net.id) # Include generated/existing NeuroML2 files ls.include_neuroml2_file('%s.cell.nml'%exc_group_component) ls.include_neuroml2_file('%s.cell.nml'%inh_group_component) ls.include_neuroml2_file(nml_file) # Specify Displays and Output Files disp_exc = "display_exc" ls.create_display(disp_exc, "Voltages Exc cells", "-80", "50") of_exc = 'Volts_file_exc' ls.create_output_file(of_exc, "v_exc.dat") disp_inh = "display_inh" ls.create_display(disp_inh, "Voltages Inh cells", "-80", "50") of_inh = 'Volts_file_inh' ls.create_output_file(of_inh, "v_inh.dat") for i in range(numCells_exc): quantity = "%s/%i/%s/v"%(exc_group, i, exc_group_component) ls.add_line_to_display(disp_exc, "Exc %i: Vm"%i, quantity, "1mV", pynml.get_next_hex_color()) ls.add_column_to_output_file(of_exc, "v_%i"%i, quantity) for i in range(numCells_inh): quantity = "%s/%i/%s/v"%(inh_group, i, inh_group_component) ls.add_line_to_display(disp_inh, "Inh %i: Vm"%i, quantity, "1mV", pynml.get_next_hex_color()) ls.add_column_to_output_file(of_inh, "v_%i"%i, quantity) # Save to LEMS XML file lems_file_name = ls.save_to_file() print "-----------------------------------"
k="0.025per_ms", erev="0mV") nml_doc.graded_synapses.append(grad_syn) pfs = PoissonFiringSynapse(id='pfs', average_rate='150Hz', synapse=syn0.id, spike_target="./%s" % syn0.id) nml_doc.poisson_firing_synapses.append(pfs) net = Network(id="CompleteNet", type="networkWithTemperature", temperature="6.3 degC") net.notes = "Network notes..." nml_doc.networks.append(net) size0 = int(5 * scale) pop0 = Population(id="IafPop0", component=IafCell0.id, size=size0) net.populations.append(pop0) size1 = int(5 * scale) pop1 = Population(id="IafPop1", component=IafCell1.id, size=size1) net.populations.append(pop1) size2 = int(5 * scale) pop2 = Population(id="IzhPop", component=iz0.id, size=size2)
nml_doc.iaf_cells.append(IafCell1) syn0 = ExpOneSynapse(id="syn0", gbase="65nS", erev="0mV", tau_decay="3ms") nml_doc.exp_one_synapses.append(syn0) pfs = PoissonFiringSynapse(id='pfs', average_rate='50Hz', synapse=syn0.id, spike_target="./%s" % syn0.id) nml_doc.poisson_firing_synapses.append(pfs) net = Network(id="IafNet") net.notes = "Netw notes" nml_doc.networks.append(net) size0 = 5 * scale pop0 = Population(id="IafPop0", component=IafCell0.id, size=size0) net.populations.append(pop0) size1 = 5 * scale pop1 = Population(id="IafPop1", component=IafCell0.id, size=size1) net.populations.append(pop1) cell_num = 4 * scale pop = Population(id="Pop_x",
erev="0mV", tau_decay="3ms") nml_doc.exp_one_synapses.append(syn0) pfs = PoissonFiringSynapse(id='pfs', average_rate='50Hz', synapse=syn0.id, spike_target="./%s"%syn0.id) nml_doc.poisson_firing_synapses.append(pfs) net = Network(id="IafNet") net.notes = "Netw notes" nml_doc.networks.append(net) size0 = 5*scale pop0 = Population(id="IafPop0", component=IafCell0.id, size=size0) net.populations.append(pop0) size1 = 5*scale pop1 = Population(id="IafPop1", component=IafCell0.id, size=size1)
def generate_granule_cell_layer(network_id, x_size, # um y_size, # um z_size, # um numCells_mf, numCells_grc, numCells_gol, mf_group_component = "MossyFiber", grc_group_component = "Granule_98", gol_group_component = "Golgi_98", connections = True, connection_probability_grc_gol = 0.2, connection_probability_gol_grc = 0.1, inputs = False, input_firing_rate = 50, # Hz num_inputs_per_mf = 4, validate = True, random_seed = 1234, generate_lems_simulation = False, duration = 500, # ms dt = 0.005, temperature="32.0 degC"): seed(random_seed) nml_doc = NeuroMLDocument(id=network_id) net = Network(id = network_id, type = "networkWithTemperature", temperature = temperature) net.notes = "Network generated using libNeuroML v%s"%__version__ nml_doc.networks.append(net) if numCells_mf>0: nml_doc.includes.append(IncludeType(href='%s.cell.nml'%mf_group_component)) if numCells_grc>0: nml_doc.includes.append(IncludeType(href='%s.cell.nml'%grc_group_component)) if numCells_gol>0: nml_doc.includes.append(IncludeType(href='%s.cell.nml'%gol_group_component)) # The names of the groups/populations mf_group = "MossyFibers" grc_group = "Grans" gol_group = "Golgis" # The names of the synapse types (should match names at Cell Mechanism/Network tabs in neuroConstruct)= mf_grc_syn = "MF_AMPA" grc_gol_syn = "AMPA_GranGol" gol_grc_syn = "GABAA" for syn in [mf_grc_syn, grc_gol_syn, gol_grc_syn]: nml_doc.includes.append(IncludeType(href='%s.synapse.nml'%syn)) # Generate Gran cells if numCells_mf>0: add_population_in_rectangular_region(net, mf_group, mf_group_component, numCells_mf, 0, 0, 0, x_size, y_size, z_size, color="0 0 1") # Generate Gran cells if numCells_grc>0: add_population_in_rectangular_region(net, grc_group, grc_group_component, numCells_grc, 0, 0, 0, x_size, y_size, z_size, color="1 0 0") # Generate Golgi cells if numCells_gol>0: add_population_in_rectangular_region(net, gol_group, gol_group_component, numCells_gol, 0, 0, 0, x_size, y_size, z_size, color="0 1 0") if connections: add_probabilistic_projection(net, mf_group, mf_group_component, grc_group, grc_group_component, 'NetConn', mf_grc_syn, numCells_mf, numCells_grc, 0.01) add_probabilistic_projection(net, grc_group, grc_group_component, gol_group, gol_group_component, 'NetConn', grc_gol_syn, numCells_grc, numCells_gol, connection_probability_grc_gol) add_probabilistic_projection(net, gol_group, gol_group_component, grc_group, grc_group_component, 'NetConn', gol_grc_syn, numCells_gol, numCells_grc, connection_probability_gol_grc) if inputs: mf_input_syn = "MFSpikeSyn" nml_doc.includes.append(IncludeType(href='%s.synapse.nml'%mf_input_syn)) rand_spiker_id = "input%sHz"%input_firing_rate #<poissonFiringSynapse id="Input_8" averageRate="50.0 per_s" synapse="MFSpikeSyn" spikeTarget="./MFSpikeSyn"/> pfs = PoissonFiringSynapse(id=rand_spiker_id, average_rate="%s per_s"%input_firing_rate, synapse=mf_input_syn, spike_target="./%s"%mf_input_syn) nml_doc.poisson_firing_synapses.append(pfs) input_list = InputList(id="Input_0", component=rand_spiker_id, populations=mf_group) count = 0 for i in range(0, numCells_mf): for j in range(num_inputs_per_mf): input = Input(id=count, target="../%s/%i/%s"%(mf_group, i, mf_group_component), destination="synapses") input_list.input.append(input) count += 1 net.input_lists.append(input_list) ####### Write to file ###### print("Saving to file...") nml_file = network_id+'.net.nml' writers.NeuroMLWriter.write(nml_doc, nml_file) print("Written network file to: "+nml_file) if validate: ###### Validate the NeuroML ###### from neuroml.utils import validate_neuroml2 validate_neuroml2(nml_file) if generate_lems_simulation: # Create a LEMSSimulation to manage creation of LEMS file ls = LEMSSimulation("Sim_%s"%network_id, duration, dt) # Point to network as target of simulation ls.assign_simulation_target(net.id) # Include generated/existing NeuroML2 files ls.include_neuroml2_file('%s.cell.nml'%grc_group_component) ls.include_neuroml2_file('%s.cell.nml'%gol_group_component) ls.include_neuroml2_file(nml_file) # Specify Displays and Output Files if numCells_mf>0: disp_mf = "display_mf" ls.create_display(disp_mf, "Voltages Mossy fibers", "-70", "10") of_mf = 'Volts_file_mf' ls.create_output_file(of_mf, "v_mf.dat") for i in range(numCells_mf): quantity = "%s/%i/%s/v"%(mf_group, i, mf_group_component) ls.add_line_to_display(disp_mf, "MF %i: Vm"%i, quantity, "1mV", pynml.get_next_hex_color()) ls.add_column_to_output_file(of_mf, "v_%i"%i, quantity) # Specify Displays and Output Files if numCells_grc>0: disp_grc = "display_grc" ls.create_display(disp_grc, "Voltages Granule cells", "-75", "30") of_grc = 'Volts_file_grc' ls.create_output_file(of_grc, "v_grc.dat") for i in range(numCells_grc): quantity = "%s/%i/%s/v"%(grc_group, i, grc_group_component) ls.add_line_to_display(disp_grc, "GrC %i: Vm"%i, quantity, "1mV", pynml.get_next_hex_color()) ls.add_column_to_output_file(of_grc, "v_%i"%i, quantity) if numCells_gol>0: disp_gol = "display_gol" ls.create_display(disp_gol, "Voltages Golgi cells", "-75", "30") of_gol = 'Volts_file_gol' ls.create_output_file(of_gol, "v_gol.dat") for i in range(numCells_gol): quantity = "%s/%i/%s/v"%(gol_group, i, gol_group_component) ls.add_line_to_display(disp_gol, "Golgi %i: Vm"%i, quantity, "1mV", pynml.get_next_hex_color()) ls.add_column_to_output_file(of_gol, "v_%i"%i, quantity) # Save to LEMS XML file lems_file_name = ls.save_to_file() else: ls = None print "-----------------------------------" return nml_doc, ls
from neuroml import NeuroMLDocument from neuroml import PoissonFiringSynapse from neuroml import Population from neuroml import Projection from neuroml import Property import neuroml.writers as writers import random import math nml_doc = NeuroMLDocument(id="Example2") nml_doc.notes = "Demo of cell with spines" net = Network(id=nml_doc.id) net.notes = nml_doc.notes nml_doc.networks.append(net) populations = {} def add_instance(name, x, y, z): pop = populations[name] inst = Instance(id=len(pop.instances)) pop.size = pop.size + 1 pop.instances.append(inst) inst.location = Location(x=x, y=y, z=z) def on_circle(fract, radius):