Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: 'Property' object has no attribute 'includes' #91

Open
sanjayankur31 opened this issue Feb 3, 2021 · 3 comments
Open

Comments

@sanjayankur31
Copy link
Contributor

Description

While using the -graph option with pynml on a simple network example, pynml crashes with this error.

Versions of software

pyNeuroML v0.5.6: Python utilities for NeuroML2
    libNeuroML v0.2.52
    jNeuroML v0.10.1

How reproducible

Always

Steps to reproduce

  1. Run this python script to generate the NeuroML/LEMS descriptions:
#!/usr/bin/env python3
"""
Create a simple network with two populations.
"""

from neuroml import NeuroMLDocument
from neuroml import Izhikevich2007Cell
from neuroml import Network
from neuroml import ExpOneSynapse
from neuroml import Population
from neuroml import Projection
from neuroml import PulseGenerator
from neuroml import ExplicitInput
from neuroml import Connection
import neuroml.writers as writers
import random
from pyneuroml import pynml
from pyneuroml.lems import LEMSSimulation
import numpy as np


nml_doc = NeuroMLDocument(id="IzNet")

iz0 = Izhikevich2007Cell(
    id="iz2007RS0", v0="-60mV", C="100pF", k="0.7nS_per_mV", vr="-60mV",
    vt="-40mV", vpeak="35mV", a="0.03per_ms", b="-2nS", c="-50.0mV", d="100pA")
nml_doc.izhikevich2007_cells.append(iz0)

syn0 = ExpOneSynapse(id="syn0", gbase="65nS", erev="0mV", tau_decay="3ms")
nml_doc.exp_one_synapses.append(syn0)

net = Network(id="IzNet")
nml_doc.networks.append(net)

size0 = 5
pop0 = Population(id="IzPop0", component=iz0.id, size=size0)
net.populations.append(pop0)

size1 = 5
pop1 = Population(id="IzPop1", component=iz0.id, size=size1)
net.populations.append(pop1)

proj = Projection(id='proj', presynaptic_population=pop0.id,
                  postsynaptic_population=pop1.id, synapse=syn0.id)
net.projections.append(proj)

random.seed(921)
prob_connection = 0.5
count = 0
for pre in range(0, size0):
    pg = PulseGenerator(
        id="pulseGen_%i" % pre, delay="0ms", duration="10000ms",
        amplitude="%f nA" % (0.1 * random.random())
    )
    nml_doc.pulse_generators.append(pg)

    exp_input = ExplicitInput(target="%s[%i]" % (pop0.id, pre), input=pg.id)
    net.explicit_inputs.append(exp_input)

    for post in range(0, size1):
        if random.random() <= prob_connection:
            syn = Connection(id=count,
                             pre_cell_id="../%s[%i]" % (pop0.id, pre),
                             synapse=syn0.id,
                             post_cell_id="../%s[%i]" % (pop1.id, post))
            proj.connections.append(syn)
            count += 1

nml_file = 'izhikevich2007_network.nml'
writers.NeuroMLWriter.write(nml_doc, nml_file)

print("Written network file to: " + nml_file)
pynml.validate_neuroml2(nml_file)

simulation_id = "example_izhikevich2007network_sim"
simulation = LEMSSimulation(sim_id=simulation_id,
                            duration=10000, dt=0.1, simulation_seed=123)
simulation.assign_simulation_target(net.id)
simulation.include_neuroml2_file(nml_file)

simulation.create_event_output_file(
    "pop0", "%s.spikes.dat" % simulation_id, format='ID_TIME'
)

for pre in range(0, size0):
    simulation.add_selection_to_event_output_file(
        "pop0", pre, 'IzPop0/{}'.format(pre), 'spike')

lems_simulation_file = simulation.save_to_file()

pynml.run_lems_with_jneuroml_neuron(
    lems_simulation_file, max_memory="20G", nogui=True, plot=False
)

# Load the data from the file and plot the spike times
# using the pynml generate_plot utility function.
data_array = np.loadtxt("%s.spikes.dat" % simulation_id)
pynml.generate_plot(
    [data_array[:, 1]], [data_array[:, 0]],
    "Spike times", show_plot_already=False,
    save_figure_to="%s-spikes.png" % simulation_id,
    xaxis="time (s)", yaxis="cell ID",
    linestyles='', linewidths='0', markers=['.'],
)

So:

python izhikevich-network.py
  1. On the generated LEMS file, run pynml -graph:
$ pynml LEMS_example_izhikevich2007network_sim.xml -graph 1
neuromllite >>> Initiating GraphViz handler, level 1, engine: dot, seed: 1234
Parsing: LEMS_example_izhikevich2007network_sim.xml
Traceback (most recent call last):
  File "/usr/bin/pynml", line 33, in <module>
    sys.exit(load_entry_point('pyNeuroML==0.5.6', 'console_scripts', 'pynml')())
  File "/usr/lib/python3.9/site-packages/pyneuroml/pynml.py", line 1644, in main
    evaluate_arguments(args)
  File "/usr/lib/python3.9/site-packages/pyneuroml/pynml.py", line 1165, in evaluate_arguments
    currParser.parse(args.lems_file)
  File "/usr/lib/python3.9/site-packages/neuroml/hdf5/NeuroMLXMLParser.py", line 77, in parse
    self.nml_doc = loaders.read_neuroml2_file(filename,
  File "/usr/lib/python3.9/site-packages/neuroml/loaders.py", line 239, in read_neuroml2_file
    return _read_neuroml2(nml2_file_name, include_includes=include_includes, verbose=verbose,
  File "/usr/lib/python3.9/site-packages/neuroml/loaders.py", line 279, in _read_neuroml2
    for include in nml2_doc.includes:
AttributeError: 'Property' object has no attribute 'includes'

Additional information

jnml seems to work fine:

jnml LEMS_example_izhikevich2007network_sim.xml -graph
 jNeuroML v0.10.1
(INFO) Reading from: /home/asinha/Documents/02_Code/00_mine/2020-OSB/NeuroML-Documentation/source/Userdocs/NML2_examples/LEMS_example_izhikevich2007network_sim.xml
(INFO) simCpt: Component(id=example_izhikevich2007network_sim type=Simulation)
Writing to: /home/asinha/Documents/02_Code/00_mine/2020-OSB/NeuroML-Documentation/source/Userdocs/NML2_examples/LEMS_example_izhikevich2007network_sim.gv
Have successfully run command: dot -Tpng  /home/asinha/Documents/02_Code/00_mine/2020-OSB/NeuroML-Documentation/source/Userdocs/NML2_examples/LEMS_example_izhikevich2007network_sim.gv -o /home/asinha/Documents/02_Code/00_mine/2020-OSB/NeuroML-Documentation/source/Userdocs/NML2_examples/LEMS_example_izhikevich2007network_sim.png

I expect it's because it's looking for includes in for include in nml2_doc.includes, but this rather simple NeuroML document generated by this doesn't have any includes?

<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.1.xsd" id="IzNet">
    <expOneSynapse id="syn0" gbase="65nS" erev="0mV" tauDecay="3ms"/>
    <izhikevich2007Cell id="iz2007RS0" C="100pF" v0="-60mV" k="0.7nS_per_mV" vr="-60mV" vt="-40mV" vpeak="35mV" a="0.03per_ms" b="-2nS" c="-50.0mV" d="100pA"/>
    <pulseGenerator id="pulseGen_0" delay="0ms" duration="10000ms" amplitude="0.098292 nA"/>
    <pulseGenerator id="pulseGen_1" delay="0ms" duration="10000ms" amplitude="0.076471 nA"/>
    <pulseGenerator id="pulseGen_2" delay="0ms" duration="10000ms" amplitude="0.033444 nA"/>
    <pulseGenerator id="pulseGen_3" delay="0ms" duration="10000ms" amplitude="0.010134 nA"/>
    <pulseGenerator id="pulseGen_4" delay="0ms" duration="10000ms" amplitude="0.080287 nA"/>
    <network id="IzNet">
        <population id="IzPop0" component="iz2007RS0" size="5"/>
        <population id="IzPop1" component="iz2007RS0" size="5"/>
        <projection id="proj" presynapticPopulation="IzPop0" postsynapticPopulation="IzPop1" synapse="syn0">
            <connection id="0" preCellId="../IzPop0[0]" postCellId="../IzPop1[0]"/>
            <connection id="1" preCellId="../IzPop0[0]" postCellId="../IzPop1[1]"/>
            <connection id="2" preCellId="../IzPop0[0]" postCellId="../IzPop1[3]"/>
            <connection id="3" preCellId="../IzPop0[1]" postCellId="../IzPop1[1]"/>
            <connection id="4" preCellId="../IzPop0[1]" postCellId="../IzPop1[3]"/>
            <connection id="5" preCellId="../IzPop0[2]" postCellId="../IzPop1[2]"/>
            <connection id="6" preCellId="../IzPop0[2]" postCellId="../IzPop1[3]"/>
            <connection id="7" preCellId="../IzPop0[3]" postCellId="../IzPop1[2]"/>
            <connection id="8" preCellId="../IzPop0[4]" postCellId="../IzPop1[1]"/>
        </projection>
        <explicitInput target="IzPop0[0]" input="pulseGen_0"/>
        <explicitInput target="IzPop0[1]" input="pulseGen_1"/>
        <explicitInput target="IzPop0[2]" input="pulseGen_2"/>
        <explicitInput target="IzPop0[3]" input="pulseGen_3"/>
        <explicitInput target="IzPop0[4]" input="pulseGen_4"/>
    </network>
</neuroml>
@sanjayankur31
Copy link
Contributor Author

Hrm, no, it doesn't get past the LEMS file to get to the NeuroML file at all, and the LEMS file does have includes in it.

<Lems>
    
    <!-- 

        This LEMS file has been automatically generated using PyNeuroML v0.5.6 (libNeuroML v0.2.52)

     -->
    
    <!-- Specify which component to run -->
    <Target component="example_izhikevich2007network_sim"/>

    <!-- Include core NeuroML2 ComponentType definitions -->
    <Include file="Cells.xml"/>
    <Include file="Networks.xml"/>
    <Include file="Simulation.xml"/>
    
    <Include file="izhikevich2007_network.nml"/>
   
    <Simulation id="example_izhikevich2007network_sim" length="10000ms" step="0.1ms" target="IzNet" seed="123">  <!-- Note seed: ensures same random numbers used every run -->
        
        <EventOutputFile id="pop0" fileName="example_izhikevich2007network_sim.spikes.dat" format="ID_TIME">
            <EventSelection id="0" select="IzPop0/0" eventPort="spike"/> 
            <EventSelection id="1" select="IzPop0/1" eventPort="spike"/> 
            <EventSelection id="2" select="IzPop0/2" eventPort="spike"/> 
            <EventSelection id="3" select="IzPop0/3" eventPort="spike"/> 
            <EventSelection id="4" select="IzPop0/4" eventPort="spike"/> 
        </EventOutputFile>
        
    </Simulation>

</Lems>

@pgleeson
Copy link
Member

@sanjayankur31 I've added a check at each pynml option to see if it's a LEMS or NML file, depending on what the option expects. If it gets the wrong one, it prints a warning which should help avoid this:

Screenshot 2021-02-17 at 14 03 03

Note: it's only a simple check on the name of the file (LEMS_* or *.nml), and doesn't prevent the option being executed, but should catch most cases.

@sanjayankur31
Copy link
Contributor Author

OK, that'll do for a start. (I still don't like that it can cause a crash with an ugly stacktrace 😆 )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants