diff --git a/pom.xml b/pom.xml index 8df75dd3a..96bf28ef9 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.neuroml.export org.neuroml.export bundle - 1.10.0 + 1.10.1 org.neuroml.export http://maven.apache.org @@ -18,12 +18,12 @@ org.neuroml.model org.neuroml.model - 1.10.0 + 1.10.1 org.lemsml jlems - 0.11.0 + 0.11.1 org.apache.velocity @@ -49,7 +49,7 @@ <br /> <br /> - Copyright NeuroML Contributors 2023 + Copyright NeuroML Contributors 2024 diff --git a/src/main/java/org/lemsml/export/dlems/DLemsWriter.java b/src/main/java/org/lemsml/export/dlems/DLemsWriter.java index 237c8688a..270da55bb 100644 --- a/src/main/java/org/lemsml/export/dlems/DLemsWriter.java +++ b/src/main/java/org/lemsml/export/dlems/DLemsWriter.java @@ -673,8 +673,21 @@ private void writeDLemsForComponent(JsonGenerator g, Component comp, HashMap standalones = Utils.convertLemsComponentToNeuroML(component); + LinkedHashMap standalones = Utils.convertLemsComponentToNeuroML(component, true, null); for(Standalone element : standalones.values()) { diff --git a/src/main/java/org/neuroml/export/netpyne/NetPyNEWriter.java b/src/main/java/org/neuroml/export/netpyne/NetPyNEWriter.java index 04b8aea0e..931a63310 100644 --- a/src/main/java/org/neuroml/export/netpyne/NetPyNEWriter.java +++ b/src/main/java/org/neuroml/export/netpyne/NetPyNEWriter.java @@ -97,6 +97,7 @@ public void setSupportedFeatures() { sli.addSupportInfo(format, ModelFeature.ABSTRACT_CELL_MODEL, SupportLevelInfo.Level.HIGH); sli.addSupportInfo(format, ModelFeature.COND_BASED_CELL_MODEL, SupportLevelInfo.Level.HIGH); + sli.addSupportInfo(format, ModelFeature.EXT_MORPH_BIOPHYS_CELL_MODEL, SupportLevelInfo.Level.HIGH); sli.addSupportInfo(format, ModelFeature.SINGLE_COMP_MODEL, SupportLevelInfo.Level.HIGH); sli.addSupportInfo(format, ModelFeature.NETWORK_MODEL, SupportLevelInfo.Level.HIGH); sli.addSupportInfo(format, ModelFeature.MULTI_CELL_MODEL, SupportLevelInfo.Level.HIGH); @@ -472,6 +473,11 @@ public static void main(String[] args) throws Exception //lemsFiles.add(new File("../neuroConstruct/osb/olfactorybulb/networks/MiglioreEtAl14_OlfactoryBulb3D/NeuroML2/Channels/test/LEMS_OlfactoryTest_12.xml")); //lemsFiles.add(new File("../neuroConstruct/osb/generic/hodgkin_huxley_tutorial/Tutorial/Source/LEMS_HH_Simulation.xml")); //lemsFiles.add(new File("../git/multi/temp/LEMS_ISN_net.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/ACnet2/neuroConstruct/generatedNeuroML2/LEMS_ACNet2.xml")); + lemsFiles.add(new File("../git/morphology_include/LEMS_m_in_b_in.xml")); + lemsFiles.add(new File("../git/morphology_include/LEMS_m_out_b_in.xml")); + lemsFiles.add(new File("../git/morphology_include/LEMS_m_out_b_out.xml")); + //lemsFiles.add(new File("../git/morphology_include/LEMS_m_in_b_out.xml")); for (File lemsFile : lemsFiles) { diff --git a/src/main/java/org/neuroml/export/neuron/NamingHelper.java b/src/main/java/org/neuroml/export/neuron/NamingHelper.java index a51024d23..87df3170a 100644 --- a/src/main/java/org/neuroml/export/neuron/NamingHelper.java +++ b/src/main/java/org/neuroml/export/neuron/NamingHelper.java @@ -13,6 +13,7 @@ import org.neuroml.model.Segment; import org.neuroml.model.SegmentGroup; import org.neuroml.model.util.CellUtils; +import org.neuroml.model.util.NeuroMLException; /** * @@ -31,7 +32,7 @@ public NamingHelper(Cell cell) this.cell = cell; } - public String getNrnSectionName(Segment seg) + public String getNrnSectionName(Segment seg) throws NeuroMLException { String uniqueId = cell.getId() + ":" + seg.getId(); diff --git a/src/main/java/org/neuroml/export/neuron/NeuronWriter.java b/src/main/java/org/neuroml/export/neuron/NeuronWriter.java index 08c846388..8d1d509a9 100644 --- a/src/main/java/org/neuroml/export/neuron/NeuronWriter.java +++ b/src/main/java/org/neuroml/export/neuron/NeuronWriter.java @@ -132,6 +132,7 @@ public void setSupportedFeatures() { sli.addSupportInfo(format, ModelFeature.ABSTRACT_CELL_MODEL, SupportLevelInfo.Level.MEDIUM); sli.addSupportInfo(format, ModelFeature.COND_BASED_CELL_MODEL, SupportLevelInfo.Level.MEDIUM); + sli.addSupportInfo(format, ModelFeature.EXT_MORPH_BIOPHYS_CELL_MODEL, SupportLevelInfo.Level.HIGH); sli.addSupportInfo(format, ModelFeature.SINGLE_COMP_MODEL, SupportLevelInfo.Level.MEDIUM); sli.addSupportInfo(format, ModelFeature.NETWORK_MODEL, SupportLevelInfo.Level.LOW); sli.addSupportInfo(format, ModelFeature.MULTI_CELL_MODEL, SupportLevelInfo.Level.MEDIUM); @@ -2071,7 +2072,7 @@ private Cell getCellFromComponent(Component cellComponent) throws LEMSException, } else { - cell = Utils.getCellFromComponent(cellComponent); + cell = Utils.getCellFromComponent(cellComponent, lems); compIdsVsCells.put(cellComponent.getID(), cell); } return cell; @@ -2105,7 +2106,11 @@ public IntracellularProperties convertCellWithMorphology(Component cellComponent { BiophysicalProperties bp = cell.getBiophysicalProperties(); ip = bp.getIntracellularProperties(); - bpComp = cellComponent.getChild("biophysicalProperties"); + bpComp = cellComponent.quietGetChild("biophysicalProperties"); + if (bpComp==null) + { + bpComp = lems.getComponent(bp.getId()); + } mpComp = bpComp.getChild("membraneProperties"); ipComp = bpComp.getChild("intracellularProperties"); } @@ -3936,8 +3941,8 @@ public static void main(String[] args) throws Exception ArrayList lemsFiles = new ArrayList(); - lemsFiles.add(new File("../neuroConstruct/osb/hippocampus/interneurons/WangBuzsaki1996/NeuroML2/LEMS_ComponentType/LEMS_WangBuzsaki.xml")); - lemsFiles.add(new File("../neuroConstruct/osb/generic/HindmarshRose1984/NeuroML2/LEMS_Regular_HindmarshRoseNML.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/hippocampus/interneurons/WangBuzsaki1996/NeuroML2/LEMS_ComponentType/LEMS_WangBuzsaki.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/generic/HindmarshRose1984/NeuroML2/LEMS_Regular_HindmarshRoseNML.xml")); //lemsFiles.add(new File("../neuroConstruct/osb/showcase/StochasticityShowcase/NeuroML2/LEMS_Inputs0.xml")); //lemsFiles.add(new File("../neuroConstruct/osb/invertebrate/celegans/CElegansNeuroML/CElegans/pythonScripts/c302/examples/LEMS_c302_C1_Oscillator.xml")); @@ -3947,14 +3952,14 @@ public static void main(String[] args) throws Exception //lemsFiles.add(new File("../neuroConstruct/osb/cerebellum/networks/VervaekeEtAl-GolgiCellNetwork/NeuroML2/LEMS_Pacemaking.xml")); //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex9_FN.xml")); lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex5_DetCell.xml")); - lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex15_CaDynamics.xml")); - lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/IzhikevichModel/NeuroML2/LEMS_2007One.xml")); + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex15_CaDynamics.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/IzhikevichModel/NeuroML2/LEMS_2007One.xml")); //lemsFiles.add(new File("../org.neuroml.export/src/test/resources/examples/LEMS_SpikePass2.xml")); /* lemsFiles.add(new File("../neuroConstruct/osb/showcase/StochasticityShowcase/NeuroML2/LEMS_NoisyCurrentInput.xml")); lemsFiles.add(new File("../neuroConstruct/osb/showcase/StochasticityShowcase/NeuroML2/LEMS_OUCurrentInput_test.xml")); lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/IzhikevichModel/NeuroML2/LEMS_FiveCells.xml"));*/ - lemsFiles.add(new File("../git/ca1/NeuroML2/channels/test_Cadynamics/NeuroML2/LEMS_test_Ca.xml")); + //lemsFiles.add(new File("../git/ca1/NeuroML2/channels/test_Cadynamics/NeuroML2/LEMS_test_Ca.xml")); //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex20a_AnalogSynapsesHH.xml")); //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex20_AnalogSynapses.xml")); //lemsFiles.add(new File("../NeuroMLlite/neuromllite/LEMS_Sim_ten_cells_spikes_nest.xml")); @@ -3976,7 +3981,11 @@ public static void main(String[] args) throws Exception // // lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/multiple/PospischilEtAl2008/NeuroML2/channels/Na/LEMS_Na.xml")); // lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/multiple/PospischilEtAl2008/NeuroML2/channels/Kd/LEMS_Kd.xml")); -// lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/ACnet2/neuroConstruct/generatedNeuroML2/LEMS_MediumNet.xml")); + lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/ACnet2/neuroConstruct/generatedNeuroML2/LEMS_ACNet2.xml")); + lemsFiles.add(new File("../git/morphology_include/LEMS_m_in_b_in.xml")); + lemsFiles.add(new File("../git/morphology_include/LEMS_m_out_b_in.xml")); + lemsFiles.add(new File("../git/morphology_include/LEMS_m_in_b_out.xml")); + // lemsFiles.add(new File("../OpenCortex/examples/LEMS_ACNet.xml")); // //lemsFiles.add(new File("../OpenCortex/examples/LEMS_SpikingNet.xml")); @@ -3995,7 +4004,7 @@ public static void main(String[] args) throws Exception // lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex25_MultiComp.xml")); // lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/LEMS_HybridTut.xml")); // lemsFiles.add(new File("../OpenCortex/examples/LEMS_L23TraubDemo_1cells_0conns.xml")); - lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex0_IaF.xml")); + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex0_IaF.xml")); //lemsFiles.add(new File("../neuroConstruct/osb/invertebrate/celegans/CElegansNeuroML/CElegans/pythonScripts/c302/examples/LEMS_c302_C1_Muscles.xml")); //lemsFiles.add(new File("../neuroConstruct/osb/invertebrate/celegans/CElegansNeuroML/CElegans/pythonScripts/c302/examples/LEMS_c302_C1_Syns.xml")); diff --git a/src/main/java/org/neuroml/export/svg/Network3D.java b/src/main/java/org/neuroml/export/svg/Network3D.java index 2cfa0ba79..59561063f 100644 --- a/src/main/java/org/neuroml/export/svg/Network3D.java +++ b/src/main/java/org/neuroml/export/svg/Network3D.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.List; import org.neuroml.model.util.CellUtils; +import org.neuroml.model.util.NeuroMLException; public class Network3D { @@ -19,13 +20,13 @@ public Network3D(String comment) lines = new ArrayList(100); } - public Network3D(Cell cell) + public Network3D(Cell cell) throws NeuroMLException { this.comment = "Cell: "+cell.getId(); lines = extractLines(cell, null); } - public void addCell(Cell cell, float offsetX, float offsetY, float offsetZ, String defaultColor) + public void addCell(Cell cell, float offsetX, float offsetY, float offsetZ, String defaultColor) throws NeuroMLException { lines.addAll(extractLines(cell, offsetX, offsetY, offsetZ, defaultColor)); } @@ -201,13 +202,13 @@ private Network3D rotate(double degreesAroundZ, double degreesAroundY) } - private ArrayList extractLines(Cell cell, String defaultColor) + private ArrayList extractLines(Cell cell, String defaultColor) throws NeuroMLException { return extractLines(cell, 0, 0, 0, defaultColor); } - private ArrayList extractLines(Cell cell, float offsetX, float offsetY, float offsetZ, String defaultColor) + private ArrayList extractLines(Cell cell, float offsetX, float offsetY, float offsetZ, String defaultColor) throws NeuroMLException { ArrayList result = new ArrayList(); diff --git a/src/main/java/org/neuroml/export/svg/SVGWriter.java b/src/main/java/org/neuroml/export/svg/SVGWriter.java index 7733ead43..de92ffe5e 100644 --- a/src/main/java/org/neuroml/export/svg/SVGWriter.java +++ b/src/main/java/org/neuroml/export/svg/SVGWriter.java @@ -82,21 +82,27 @@ public String getMainScript() throws GenerationException { StringBuilder core = new StringBuilder(); - Rectangle bounds = render(core, false); - StringBuilder result = new StringBuilder(); - //Add header - result.append("\n"); - //addComment(result, "Total bounds: "+bounds.toString()); - startElement(result, "svg", "xmlns=" + SVG_NAMESPACE, - "version=" + SVG_VERSION, - "width="+bounds.width, - "height="+bounds.height, - "viewBox=0 0 "+bounds.width+" "+bounds.height); - - result.append(core.toString()); - - endElement(result, "svg"); + try { + + Rectangle bounds = render(core, false); + + //Add header + result.append("\n"); + //addComment(result, "Total bounds: "+bounds.toString()); + startElement(result, "svg", "xmlns=" + SVG_NAMESPACE, + "version=" + SVG_VERSION, + "width="+bounds.width, + "height="+bounds.height, + "viewBox=0 0 "+bounds.width+" "+bounds.height); + + result.append(core.toString()); + + endElement(result, "svg"); + } + catch (NeuroMLException ne) { + throw new GenerationException("Problem generating SVG", ne); + } return result.toString(); } @@ -107,7 +113,7 @@ public List getAllBasedOnCell(NeuroMLDocument nmlDocument) { return cells; } - public Rectangle render(StringBuilder result, boolean png) { + public Rectangle render(StringBuilder result, boolean png) throws NeuroMLException { if (nmlDocument.getNetwork().isEmpty()) { @@ -185,7 +191,7 @@ public Rectangle render(StringBuilder result, boolean png) { } } - public void convertToPng(File pngFile) { + public void convertToPng(File pngFile) throws NeuroMLException { // One quick run to get bounds... Rectangle bounds = render(new StringBuilder(), false); diff --git a/src/main/java/org/neuroml/export/utils/Utils.java b/src/main/java/org/neuroml/export/utils/Utils.java index b1d26dbb6..96b88c52c 100644 --- a/src/main/java/org/neuroml/export/utils/Utils.java +++ b/src/main/java/org/neuroml/export/utils/Utils.java @@ -30,6 +30,8 @@ import org.neuroml.export.utils.support.SupportLevelInfo; import org.neuroml.model.Cell; import org.neuroml.model.Cell2CaPools; +import org.neuroml.model.Morphology; +import org.neuroml.model.BiophysicalProperties; import org.neuroml.model.NeuroMLDocument; import org.neuroml.model.Standalone; import org.neuroml.model.util.NeuroML2Validator; @@ -42,7 +44,7 @@ public class Utils private static Lems lemsWithNML2CompTypes; - public static String ORG_NEUROML_EXPORT_VERSION = "1.10.0"; + public static String ORG_NEUROML_EXPORT_VERSION = "1.10.1"; public static final String ARCH_I686 = "i686"; public static final String ARCH_I386 = "i386"; @@ -401,11 +403,42 @@ public static NeuroMLDocument convertLemsComponentToNeuroMLDocument(Component co return nmlDocument; } - public static LinkedHashMap convertLemsComponentToNeuroML(Component comp) throws LEMSException, NeuroMLException + public static LinkedHashMap convertLemsComponentToNeuroML(Component comp, boolean fixExternalMorphsBiophys, Lems lems) throws LEMSException, NeuroMLException { NeuroMLDocument nmlDocument = convertLemsComponentToNeuroMLDocument(comp); LinkedHashMap els = NeuroMLConverter.getAllStandaloneElements(nmlDocument); + + if (fixExternalMorphsBiophys) + { + for (Map.Entry entry : els.entrySet()) + { + String id = entry.getKey(); + Standalone e = entry.getValue(); + if (e instanceof Cell) { + Cell cell = (Cell)e; + + if (cell.getMorphologyAttr() != null) + { + Component morphComp = lems.getComponent(cell.getMorphologyAttr()); + NeuroMLDocument nmlDocumentMorph = convertLemsComponentToNeuroMLDocument(morphComp); + Morphology m = nmlDocumentMorph.getMorphology().get(0); + cell.setMorphology(m); + cell.setMorphologyAttr(null); + els.put(id, cell); + } + if (cell.getBiophysicalPropertiesAttr() != null) + { + Component bpComp = lems.getComponent(cell.getBiophysicalPropertiesAttr()); + NeuroMLDocument nmlDocumentBp = convertLemsComponentToNeuroMLDocument(bpComp); + BiophysicalProperties bp = nmlDocumentBp.getBiophysicalProperties().get(0); + cell.setBiophysicalProperties(bp); + cell.setBiophysicalPropertiesAttr(null); + els.put(id, cell); + } + } + } + } return els; } @@ -423,9 +456,9 @@ public static Component convertNeuroMLToComponent(Standalone nmlElement) throws } } - public static Cell getCellFromComponent(Component comp) throws LEMSException, NeuroMLException + public static Cell getCellFromComponent(Component comp, Lems lems) throws LEMSException, NeuroMLException { - LinkedHashMap els = Utils.convertLemsComponentToNeuroML(comp); + LinkedHashMap els = Utils.convertLemsComponentToNeuroML(comp, true, lems); Cell cell = (Cell) els.values().iterator().next(); if (cell == null) { @@ -523,7 +556,15 @@ public Sim importFile(File simFile) throws LEMSException { if(run) { SupportLevelInfo sli = SupportLevelInfo.getSupportLevelInfo(); - sli.checkConversionSupported(Format.LEMS, sim.getLems()); + try + { + sli.checkConversionSupported(Format.LEMS, sim.getLems()); + } + catch (ModelFeatureSupportException mfse) + { + E.info(mfse.getMessage()); + System.exit(-1); + } sim.run(); IOUtil.saveReportAndTimesFile(sim, lemsFile); E.info("Finished reading, building, running and displaying LEMS model"); diff --git a/src/main/java/org/neuroml/export/utils/support/ModelFeature.java b/src/main/java/org/neuroml/export/utils/support/ModelFeature.java index 6063290cf..cb34f7ff7 100644 --- a/src/main/java/org/neuroml/export/utils/support/ModelFeature.java +++ b/src/main/java/org/neuroml/export/utils/support/ModelFeature.java @@ -37,6 +37,7 @@ public enum ModelFeature NETWORK_WITH_ANALOG_CONNS_MODEL("Network model with analog/continuously communicating connections between cells"), ABSTRACT_CELL_MODEL("Model with abstract (non conductance based) cell(s)"), COND_BASED_CELL_MODEL("Model with conductance based cell(s)"), + EXT_MORPH_BIOPHYS_CELL_MODEL("Model with conductance based cell(s) with morphology and/or biophysicalProperties outside cell element"), MULTICOMPARTMENTAL_CELL_MODEL("Model with multicompartmental cell(s)"), CHANNEL_POPULATIONS_CELL_MODEL("Model with channel populations"), CHANNEL_DENSITY_ON_SEGMENT("Model with channel density specified per segment (aot segmentGroup)"), @@ -106,7 +107,17 @@ private static void analyseSingleComponent(Component component, ArrayList 1) @@ -116,29 +127,34 @@ private static void analyseSingleComponent(Component component, ArrayList