while trying to use the cattr class to convert an xml representation to a python representation, I decided to convert the xml to a dictionary and then use the cattr.structure function to convert into a python object. While doing this, I discovered I couldn't convert the NewNetwork class in the modelspec test_base.py to an python objecet using the cattr.unstructure even though it worked perfectly well for the neuroML class in neuroml example directory in the neuroml2_spec.py file
from typing import List
from dataclasses import fields
import modelspec
from modelspec import field, instance_of, optional
from modelspec.base_types import Base, value_expr_types, ValueExprType, print_v
from typing import List, Dict, Any, Optional
import xml.dom.minidom
from pathlib import Path
import sys
import xml.dom.minidom
@modelspec.define
class Population(Base):
"""
Some description...
Args:
id: The id of the population
component: the component to use in the population
size: the size of the population
"""
id: str = field(validator=instance_of(str))
component: str = field(default=None, validator=optional(instance_of(str)))
size: int = field(default=None, validator=optional(instance_of(int)))
@modelspec.define
class ExplicitInput(Base):
"""
Some description...
Args:
target: the target of the input
input: the input, e.g. pulseGenerator
"""
target: str = field(default=None, validator=optional(instance_of(str)))
input: str = field(default=None, validator=optional(instance_of(str)))
@modelspec.define
class Network(Base):
"""
Some description...
Args:
id: The id of the network
populations: the pops in the net
"""
id: str = field(validator=instance_of(str))
populations: List[Population] = field(factory=list)
explicitInputs: List[ExplicitInput] = field(factory=list)
@modelspec.define
class PulseGenerator(Base):
"""
Some description...
Args:
id: The id of the pulseGenerator
delay: the delay
duration: the duration
amplitude: the amplitude
"""
id: str = field(validator=instance_of(str))
delay: str = field(validator=instance_of(str))
duration: str = field(validator=instance_of(str))
amplitude: str = field(validator=instance_of(str))
@modelspec.define
class Izhikevich2007Cell(Base):
"""
Some description...
Args:
id: The id of the cell...
"""
id: str = field(validator=instance_of(str))
C: str = field(validator=instance_of(str))
v0: str = field(validator=instance_of(str))
k: str = field(validator=instance_of(str))
vr: str = field(validator=instance_of(str))
vt: str = field(validator=instance_of(str))
vpeak: str = field(validator=instance_of(str))
a: str = field(validator=instance_of(str))
b: str = field(validator=instance_of(str))
c: str = field(validator=instance_of(str))
d: str = field(validator=instance_of(str))
@modelspec.define
class NeuroML(Base):
"""
Some description...
Args:
id: The id of the NeuroML 2 document
version: NeuroML version used
networks: The networks present
"""
id: str = field(validator=instance_of(str))
version: str = field(validator=instance_of(str))
izhikevich2007Cells: List[Izhikevich2007Cell] = field(factory=list)
pulseGenerators: List[PulseGenerator] = field(factory=list)
networks: List[Network] = field(factory=list)
nml_doc = NeuroML(id="TestNeuroML", version="NeuroML_v2.3")
izh = Izhikevich2007Cell(
id="izh2007RS0",
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",
)
nml_doc.izhikevich2007Cells.append(izh)
pg = PulseGenerator(
id="pulseGen_0", delay="100ms", duration="800ms", amplitude="0.07 nA"
)
nml_doc.pulseGenerators.append(pg)
net = Network(id="IzNet")
nml_doc.networks.append(net)
net.populations.append(Population("IzhPop0", component="izh2007RS0", size=1))
net.explicitInputs.append(ExplicitInput(target="IzhPop0[0]", input="pulseGen_0"))
print(nml_doc)
@modelspec.define
class NewCell(Base):
"""
A new cell definition
Args:
id: the cell id
neuroml2_source_file: The path to the source file
"""
id: str = field(validator=instance_of(str))
neuroml2_source_file: str = field(
default=None, validator=optional(instance_of(str))
)
@modelspec.define
class NewSynapse(Base):
"""
A new synapse definition
Args:
id: the synapse id
neuroml2_source_file: The path to the source file
tested: A boolean attribute
"""
id: str = field(validator=instance_of(str))
neuroml2_source_file: str = field(
default=None, validator=optional(instance_of(str))
)
tested: bool = field(default=None, validator=optional(instance_of(bool)))
@modelspec.define
class NewRandomConnectivity(Base):
"""
A new random connectivity definition
Args:
probability: Random probability of connection
"""
probability: ValueExprType = field(
default=None, validator=optional(instance_of(value_expr_types))
)
@modelspec.define
class NewNetwork(Base):
"""
A new network definition
Args:
id: a unique identifier for the network
cells: a list of cells
synapses: a list of synapses
version: Information on verson of NeuroMLlite
seed: Seed for random number generator used when building network
stable: Testing...
parameters: Dictionary of global parameters for the network
random_connectivity: Use random connectivity
"""
id: str = field(validator=instance_of(str))
cells: List[NewCell] = field(factory=list)
synapses: List[NewSynapse] = field(factory=list)
version: str = field(default="NeuroMLlite 0.0", validator=instance_of(str))
seed: int = field(default=None, validator=optional(instance_of(int)))
stable: bool = field(default=None, validator=optional(instance_of(bool)))
parameters: Dict[str, Any] = field(
default=None, validator=optional(instance_of(dict))
)
random_connectivity: NewRandomConnectivity = field(
default=None, validator=optional(instance_of(NewRandomConnectivity))
)
ee0: ValueExprType = field(
default=None, validator=optional(instance_of(value_expr_types))
)
ee1: ValueExprType = field(
default=None, validator=optional(instance_of(value_expr_types))
)
ee2: ValueExprType = field(
default=None, validator=optional(instance_of(value_expr_types))
)
ee3: ValueExprType = field(
default=None, validator=optional(instance_of(value_expr_types))
)
ee4: ValueExprType = field(
default=None, validator=optional(instance_of(value_expr_types))
)
ee5: ValueExprType = field(
default=None, validator=optional(instance_of(value_expr_types))
)
ee6: ValueExprType = field(
default=None, validator=optional(instance_of(value_expr_types))
)
net = NewNetwork(id="netid", parameters={"size": 3, "name": None})
net.ee0 = "str"
net.ee1 = {"a": 2}
net.ee2 = 1
net.ee3 = 1.1
net.ee4 = True
net.ee5 = [1, 2]
net.ee6 = 2
cell = NewCell(id="cellid1")
cell.neuroml2_source_file = "nnn"
cell2 = NewCell(id="cellid2")
cell2.neuroml2_source_file = "nnn2"
# net.cells.append(cell)
print(net)
print(net.cells)
print(net)
""" """
net.cells.append(cell)
net.cells.append(cell2)
syn0 = NewSynapse(id="syn0", neuroml2_source_file=None, tested=True)
net.synapses.append(syn0)
syn1 = NewSynapse(id="syn1", neuroml2_source_file="xx", tested=None)
net.synapses.append(syn1)
rc = NewRandomConnectivity(probability=0.01)
net.random_connectivity = rc
net.stable = False
print(rc)
print(net)
from cattr import structure, unstructure
nml_dict = unstructure(nml_doc)
#This is the NeuroML class being unstructured
print("This is NeuroML unstructured format")
print(nml_dict)
#This is the NeuroML class being structured
print("This is NeuroML structured format")
print(structure(nml_dict, NeuroML))
#This is the NewNetwork class being unstructured
print("This is NewNetwork unstructured format")
nml_dict2 = unstructure(net)
print(nml_dict2)
#This is the NewNetwork class being unstructured
print("This is NewNetwork structured format")
print(structure(nml_dict2, NewNetwork))
while trying to use the cattr class to convert an xml representation to a python representation, I decided to convert the xml to a dictionary and then use the cattr.structure function to convert into a python object. While doing this, I discovered I couldn't convert the NewNetwork class in the modelspec test_base.py to an python objecet using the cattr.unstructure even though it worked perfectly well for the neuroML class in neuroml example directory in the neuroml2_spec.py file