def channelpedia_xml_to_neuroml2(cpd_xml, nml2_file_name, unknowns=""): info = 'Automatic conversion of Channelpedia XML file to NeuroML2\n'+\ 'Uses: https://github.com/OpenSourceBrain/BlueBrainProjectShowcase/blob/master/Channelpedia/ChannelpediaToNeuroML2.py' print(info) root = ET.fromstring(cpd_xml) channel_id = 'Channelpedia_%s_%s' % (root.attrib['ModelName'].replace( "/", "_").replace(" ", "_").replace(".", "_"), root.attrib['ModelID']) doc = neuroml.NeuroMLDocument() metadata = osb.metadata.RDF(info) ion = root.findall('Ion')[0] chan = neuroml.IonChannelHH( id=channel_id, conductance='10pS', species=ion.attrib['Name'], notes= "This is an automated conversion to NeuroML 2 of an ion channel model from Channelpedia. " + "\nThe original channel model file can be found at: http://channelpedia.epfl.ch/ionchannels/%s" % root.attrib['ID'] + "\n\nConversion scripts at https://github.com/OpenSourceBrain/BlueBrainProjectShowcase" ) chan.annotation = neuroml.Annotation() model_url_template = 'http://channelpedia.epfl.ch/ionchannels/%s/hhmodels/%s.xml' desc = osb.metadata.Description(channel_id) metadata.descriptions.append(desc) osb.metadata.add_simple_qualifier(desc, \ 'bqmodel', \ 'isDerivedFrom', \ model_url_template%(root.attrib['ID'], root.attrib['ModelID']), \ "Channelpedia channel ID: %s, ModelID: %s; direct link to original XML model" % (root.attrib['ID'], root.attrib['ModelID'])) channel_url_template = 'http://channelpedia.epfl.ch/ionchannels/%s' osb.metadata.add_simple_qualifier(desc, \ 'bqmodel', \ 'isDescribedBy', \ channel_url_template%(root.attrib['ID']), \ "Channelpedia channel ID: %s; link to main page for channel" % (root.attrib['ID'])) for reference in root.findall('Reference'): pmid = reference.attrib['PubmedID'] #metadata = update_metadata(chan, metadata, channel_id, "http://identifiers.org/pubmed/%s"%pmid) ref_info = reference.text osb.metadata.add_simple_qualifier(desc, \ 'bqmodel', \ 'isDescribedBy', \ osb.resources.PUBMED_URL_TEMPLATE % (pmid), \ ("PubMed ID: %s is referenced in original XML\n"+\ " %s") % (pmid, ref_info)) for environment in root.findall('Environment'): for animal in environment.findall('Animal'): species = animal.attrib['Name'].lower() if species: if species in osb.resources.KNOWN_SPECIES: known_id = osb.resources.KNOWN_SPECIES[species] osb.metadata.add_simple_qualifier(desc, \ 'bqbiol', \ 'hasTaxon', \ osb.resources.NCBI_TAXONOMY_URL_TEMPLATE % known_id, \ "Known species: %s; taxonomy id: %s" % (species, known_id)) else: print("Unknown species: %s" % species) unknowns += "Unknown species: %s\n" % species for cell_type_el in environment.findall('CellType'): cell_type = cell_type_el.text.strip().lower() if cell_type: if cell_type in osb.resources.KNOWN_CELL_TYPES: known_id = osb.resources.KNOWN_CELL_TYPES[cell_type] osb.metadata.add_simple_qualifier(desc, \ 'bqbiol', \ 'isPartOf', \ osb.resources.NEUROLEX_URL_TEMPLATE % known_id, \ "Known cell type: %s; taxonomy id: %s" % (cell_type, known_id)) else: print("Unknown cell_type: %s" % cell_type) unknowns += "Unknown cell_type: %s\n" % cell_type print("Currently unknown: <<<%s>>>" % unknowns) comp_types = {} for gate in root.findall('Gates'): eq_type = gate.attrib['EqType'] gate_name = gate.attrib['Name'] target = chan.gates if eq_type == '1': g = neuroml.GateHHUndetermined(id=gate_name, type='gateHHtauInf', instances=int( float(gate.attrib['Power']))) elif eq_type == '2': g = neuroml.GateHHUndetermined(id=gate_name, type='gateHHrates', instances=int( float(gate.attrib['Power']))) for inf in gate.findall('Inf_Alpha'): equation = check_equation(inf.findall('Equation')[0].text) if eq_type == '1': new_comp_type = "%s_%s_%s" % (channel_id, gate_name, 'inf') g.steady_state = neuroml.HHVariable(type=new_comp_type) comp_type = lems.ComponentType( new_comp_type, extends="baseVoltageDepVariable") comp_type.add(lems.Constant('TIME_SCALE', '1 ms', 'time')) comp_type.add(lems.Constant('VOLT_SCALE', '1 mV', 'voltage')) comp_type.dynamics.add( lems.DerivedVariable(name='V', dimension="none", value="v / VOLT_SCALE")) comp_type.dynamics.add( lems.DerivedVariable(name='x', dimension="none", value="%s" % equation, exposure="x")) comp_types[new_comp_type] = comp_type elif eq_type == '2': new_comp_type = "%s_%s_%s" % (channel_id, gate_name, 'alpha') g.forward_rate = neuroml.HHRate(type=new_comp_type) comp_type = lems.ComponentType(new_comp_type, extends="baseVoltageDepRate") comp_type.add(lems.Constant('TIME_SCALE', '1 ms', 'time')) comp_type.add(lems.Constant('VOLT_SCALE', '1 mV', 'voltage')) comp_type.dynamics.add( lems.DerivedVariable(name='V', dimension="none", value="v / VOLT_SCALE")) comp_type.dynamics.add( lems.DerivedVariable(name='r', dimension="per_time", value="%s / TIME_SCALE" % equation, exposure="r")) comp_types[new_comp_type] = comp_type for tau in gate.findall('Tau_Beta'): equation = check_equation(tau.findall('Equation')[0].text) if eq_type == '1': new_comp_type = "%s_%s_tau" % (channel_id, gate_name) g.time_course = neuroml.HHTime(type=new_comp_type) comp_type = lems.ComponentType(new_comp_type, extends="baseVoltageDepTime") comp_type.add(lems.Constant('TIME_SCALE', '1 ms', 'time')) comp_type.add(lems.Constant('VOLT_SCALE', '1 mV', 'voltage')) comp_type.dynamics.add( lems.DerivedVariable(name='V', dimension="none", value="v / VOLT_SCALE")) comp_type.dynamics.add( lems.DerivedVariable(name='t', dimension="time", value="(%s) * TIME_SCALE" % equation, exposure="t")) comp_types[new_comp_type] = comp_type elif eq_type == '2': new_comp_type = "%s_%s_%s" % (channel_id, gate_name, 'beta') g.reverse_rate = neuroml.HHRate(type=new_comp_type) comp_type = lems.ComponentType(new_comp_type, extends="baseVoltageDepRate") comp_type.add(lems.Constant('TIME_SCALE', '1 ms', 'time')) comp_type.add(lems.Constant('VOLT_SCALE', '1 mV', 'voltage')) comp_type.dynamics.add( lems.DerivedVariable(name='V', dimension="none", value="v / VOLT_SCALE")) comp_type.dynamics.add( lems.DerivedVariable(name='r', dimension="per_time", value="%s / TIME_SCALE" % equation, exposure="r")) comp_types[new_comp_type] = comp_type target.append(g) doc.ion_channel_hhs.append(chan) doc.id = channel_id writers.NeuroMLWriter.write(doc, nml2_file_name) print("Written NeuroML 2 channel file to: " + nml2_file_name) for comp_type_name in comp_types.keys(): comp_type = comp_types[comp_type_name] ct_xml = comp_type.toxml() # Quick & dirty pretty printing.. ct_xml = ct_xml.replace('<Const', '\n <Const') ct_xml = ct_xml.replace('<Dyna', '\n <Dyna') ct_xml = ct_xml.replace('</Dyna', '\n </Dyna') ct_xml = ct_xml.replace('<Deriv', '\n <Deriv') ct_xml = ct_xml.replace('</Compone', '\n </Compone') # print("Adding definition for %s:\n%s\n"%(comp_type_name, ct_xml)) nml2_file = open(nml2_file_name, 'r') orig = nml2_file.read() new_contents = orig.replace("</neuroml>", "\n %s\n\n</neuroml>" % ct_xml) nml2_file.close() nml2_file = open(nml2_file_name, 'w') nml2_file.write(new_contents) nml2_file.close() print("Inserting metadata...") nml2_file = open(nml2_file_name, 'r') orig = nml2_file.read() new_contents = orig.replace( "<annotation/>", "\n <annotation>\n%s </annotation>\n" % metadata.to_xml(" ")) nml2_file.close() nml2_file = open(nml2_file_name, 'w') nml2_file.write(new_contents) nml2_file.close() ###### Validate the NeuroML ###### from neuroml.utils import validate_neuroml2 validate_neuroml2(nml2_file_name) return unknowns
""" Generating a Hodgkin-Huxley Ion Channel and writing it to NeuroML """ import neuroml import neuroml.writers as writers chan = neuroml.IonChannelHH(id='na', conductance='10pS', species='na', notes="This is an example voltage-gated Na channel") m_gate = neuroml.GateHHRates(id='m',instances='3') h_gate = neuroml.GateHHRates(id='h',instances='1') m_gate.forward_rate = neuroml.HHRate(type="HHExpRate", rate="0.07per_ms", midpoint="-65mV", scale="-20mV") m_gate.reverse_rate = neuroml.HHRate(type="HHSigmoidRate", rate="1per_ms", midpoint="-35mV", scale="10mV") h_gate.forward_rate = neuroml.HHRate(type="HHExpLinearRate", rate="0.1per_ms", midpoint="-55mV", scale="10mV") h_gate.reverse_rate = neuroml.HHRate(type="HHExpRate",
def generate_channel_nml2(self,bio_params,channel_params,model_params): """ Generates NeuroML2 file from ion channel parameters. :param bio_params: Biological parameters :param channel_params: Channel parameters :param model_params: NeuroML2 file parameters :return: NeuroML2 file """ unknowns = '' info = 'This is an ion channel model NeuroML2 file generated by ChannelWorm: https://github.com/openworm/ChannelWorm' channel_id='ChannelWorm_%s_%s_%s'%(model_params['channel_name'],model_params['channel_id'],model_params['model_id']) doc = neuroml.NeuroMLDocument() metadata = osb.metadata.RDF(info) desc = osb.metadata.Description(channel_id) metadata.descriptions.append(desc) osb.metadata.add_simple_qualifier(desc, 'bqmodel', 'isDerivedFrom', "ChannelWorm channel Name: %s channel ID: %s, ModelID: %s" %(model_params['channel_name'],model_params['channel_id'],model_params['model_id'])) for reference in model_params['references']: DOI = reference['doi'] pmid = reference['PMID'] ref_info = reference['citation'] osb.metadata.add_simple_qualifier(desc, 'bqmodel', 'isDescribedBy', osb.resources.PUBMED_URL_TEMPLATE % (pmid), ("DOI: %s, PubMed ID: %s \n"+ " %s") % (DOI, pmid, ref_info)) species = 'caenorhabditis elegans' if osb.resources.KNOWN_SPECIES.has_key(species): known_id = osb.resources.KNOWN_SPECIES[species] osb.metadata.add_simple_qualifier(desc, 'bqbiol', 'hasTaxon', osb.resources.NCBI_TAXONOMY_URL_TEMPLATE % known_id, "Known species: %s; taxonomy id: %s" % (species, known_id)) else: print("Unknown species: %s"%species) unknowns += "Unknown species: %s\n"%species cell_type = bio_params['cell_type'] if osb.resources.KNOWN_CELL_TYPES.has_key(cell_type): known_id = osb.resources.KNOWN_CELL_TYPES[cell_type] osb.metadata.add_simple_qualifier(desc, 'bqbiol', 'isPartOf', osb.resources.NEUROLEX_URL_TEMPLATE % known_id, "Known cell type: %s; taxonomy id: %s" % (cell_type, known_id)) else: print("Unknown cell_type: %s"%cell_type) unknowns += "Unknown cell_type: %s\n"%cell_type # for contributor in model_params['contributors']: # metadata.descriptions.append('Curator: %s (%s)'%(contributor['name'],contributor['email'])) print("Currently unknown: <<<%s>>>"%unknowns) ion = bio_params['ion_type'] unit = dict(zip(bio_params['channel_params'],bio_params['unit_chan_params'])) chan = neuroml.IonChannelHH(id=channel_id, conductance='10pS', species=ion) chan.annotation = neuroml.Annotation() target = chan.gate_hh_tau_infs for gate in bio_params['gate_params']: gate_name = gate instances = bio_params['gate_params'][gate_name]['power'] g_type='HHSigmoidVariable' if gate_name == 'vda': g = neuroml.GateHHTauInf(id=gate_name, instances=instances) v_half = str(channel_params['v_half_a']) + ' ' + str(unit['v_half_a']) k = str(channel_params['k_a']) + ' ' + str(unit['k_a']) g.steady_state = neuroml.HHRate(midpoint=v_half,scale=k,rate=1,type=g_type) if 'T_a' in channel_params: T = str(channel_params['T_a']) + ' ' + str(unit['T_a']) t_type="fixedTimeCourse" g.time_course = neuroml.HHTime(tau=T, type=t_type) target.append(g) elif gate_name == 'vdi': g = neuroml.GateHHTauInf(id=gate_name, instances=instances) v_half = str(channel_params['v_half_i']) + ' ' + str(unit['v_half_i']) k = str(channel_params['k_i']) + ' ' + str(unit['k_i']) g.steadyState = neuroml.HHTime(midpoint=v_half,scale=k,rate=1,type=g_type) if 'T_i' in channel_params: T = str(channel_params['T_i']) + ' ' + str(unit['T_i']) t_type="fixedTimeCourse" g.timeCourse = neuroml.HHTime(tau=T, type=t_type) target.append(g) # TODO: Consider ion dependent activation/inactivation nml2_file_name = model_params['file_name'] doc.ion_channel_hhs.append(chan) doc.id = channel_id writers.NeuroMLWriter.write(doc,nml2_file_name) print("Written NeuroML 2 channel file to: "+nml2_file_name) nml2_file = open(nml2_file_name, 'r') orig = nml2_file.read() new_contents = orig.replace("<annotation/>", "\n <annotation>\n%s </annotation>\n"%metadata.to_xml(" ")) nml2_file.close() nml2_file = open(nml2_file_name, 'w') nml2_file.write(new_contents) nml2_file.close() myValidator = validators.Validator() myValidator.validate_nml2(nml2_file_name) return nml2_file