diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c87f1c89c..a1b56b05d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,9 +5,9 @@ name: Java CI with Maven on: push: - branches: [ master, development, experimental, osb* ] + branches: [ master, development, experimental, osb*, test* ] pull_request: - branches: [ master, development, experimental, osb* ] + branches: [ master, development, experimental, osb*, test* ] jobs: build_and_test: @@ -16,14 +16,14 @@ jobs: strategy: fail-fast: false matrix: - java: [ '8', '11', '16', '17'] - runs-on: [ubuntu-latest, macos-11, windows-2019 ] + java: [ '8', '11', '16', '17', '19'] + runs-on: [ubuntu-latest, macos-latest, windows-2019 ] name: Test on Java ${{ matrix.Java }} on ${{ matrix.runs-on }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up JDK ${{ matrix.Java }} - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: ${{ matrix.Java }} distribution: 'temurin' diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 22602cdc2..2d1c5f0d4 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,17 +13,18 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: nelonoel/branch-name@v1.0.1 - name: Set up JDK 11 - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: java-version: 11 + distribution: 'temurin' java-package: jdk - name: Set up Python 3.9 - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.9 @@ -33,14 +34,14 @@ jobs: pip install ghp-import - name: Checkout NeuroML2 - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: NeuroML/NeuroML2 ref: development path: NeuroML2 - name: Checkout org.lemsml - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: LEMS/jLEMS ref: development @@ -48,14 +49,14 @@ jobs: - name: Checkout org.neuroml.model.injectingplugin - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: NeuroML/org.neuroml.model.injectingplugin ref: development path: org.neuroml.model.injectingplugin - name: Checkout org.neuroml.model - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: NeuroML/org.neuroml.model ref: development diff --git a/.gitignore b/.gitignore index 952c993b5..1db59846f 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,6 @@ src/test/resources/examples/*nrn.py /Test.gv /Test.png /src/test/resources/examples/report*.txt +/.classpath +/.project +/.settings diff --git a/README.md b/README.md index 012e97907..b8277b189 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ Export from NeuroML & LEMS ========================== -[![Java CI with Maven](https://github.com/NeuroML/org.neuroml.export/actions/workflows/ci.yml/badge.svg)](https://github.com/NeuroML/org.neuroml.export/actions/workflows/ci.yml) +[![Java CI with Maven](https://github.com/NeuroML/org.neuroml.export/actions/workflows/ci.yml/badge.svg)](https://github.com/NeuroML/org.neuroml.export/actions/workflows/ci.yml) [![Publish Javadocs](https://github.com/NeuroML/org.neuroml.export/actions/workflows/docs.yml/badge.svg)](https://github.com/NeuroML/org.neuroml.export/actions/workflows/docs.yml) + [![GitHub](https://img.shields.io/github/license/NeuroML/org.neuroml.export)](https://github.com/NeuroML/org.neuroml.export/blob/master/LICENSE.lesser) [![GitHub pull requests](https://img.shields.io/github/issues-pr/NeuroML/org.neuroml.export)](https://github.com/NeuroML/org.neuroml.export/pulls) [![GitHub issues](https://img.shields.io/github/issues/NeuroML/org.neuroml.export)](https://github.com/NeuroML/org.neuroml.export/issues) diff --git a/pom.xml b/pom.xml index c6e82d1bf..bb9a7c3cf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.neuroml.export org.neuroml.export bundle - 1.8.1 + 1.9.1 org.neuroml.export http://maven.apache.org @@ -18,12 +18,12 @@ org.neuroml.model org.neuroml.model - 1.8.1 + 1.9.1 org.lemsml jlems - 0.10.6 + 0.10.8 org.apache.velocity @@ -49,7 +49,7 @@ <br /> <br /> - Copyright NeuroML Contributors 2021 + Copyright NeuroML Contributors 2023 diff --git a/src/main/java/org/lemsml/export/sedml/SEDMLWriter.java b/src/main/java/org/lemsml/export/sedml/SEDMLWriter.java index 39d23a91b..92899dd80 100644 --- a/src/main/java/org/lemsml/export/sedml/SEDMLWriter.java +++ b/src/main/java/org/lemsml/export/sedml/SEDMLWriter.java @@ -22,6 +22,7 @@ import org.neuroml.export.utils.support.ModelFeature; import org.neuroml.model.util.NeuroMLException; import org.neuroml.export.utils.support.SupportLevelInfo; +import org.neuroml.export.sbml.SBMLWriter; public class SEDMLWriter extends AXMLWriter { @@ -274,24 +275,31 @@ public static void main(String[] args) throws Exception, ModelFeatureSupportExce ArrayList lemsFiles = new ArrayList(); - lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/ACnet2/neuroConstruct/generatedNeuroML2/LEMS_TwoCell.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/ACnet2/neuroConstruct/generatedNeuroML2/LEMS_TwoCell.xml")); //lemsFiles.add(new File("../OpenCortex/examples/LEMS_ACNet.xml")); //lemsFiles.add(new File("../OpenCortex/examples/LEMS_SpikingNet.xml")); //lemsFiles.add(new File("../OpenCortex/examples/LEMS_SimpleNet.xml")); lemsFiles.add(new File("../neuroConstruct/osb/showcase/SBMLShowcase/NeuroML2/LEMS_NML2_Ex9_FN.xml")); + lemsFiles.add(new File("../neuroConstruct/osb/generic/HindmarshRose1984/NeuroML2/LEMS_Regular_HindmarshRose.xml")); SEDMLWriter nw; for(File lemsFile : lemsFiles) { Lems lems = Utils.readLemsNeuroMLFile(lemsFile.getAbsoluteFile()).getLems(); - nw = new SEDMLWriter(lems, lemsFile.getParentFile(), lemsFile.getName().replaceAll(".xml", ".sedml"), lemsFile.getName(), Format.SBML); + SBMLWriter sbmlw = new SBMLWriter(lems, lemsFile.getParentFile(), lemsFile.getName().replaceAll(".xml", ".sbml")); + for(File genFile : sbmlw.convert()) + { + System.out.println("Generated SBML: " + genFile.getAbsolutePath()); + } + + nw = new SEDMLWriter(lems, lemsFile.getParentFile(), lemsFile.getName().replaceAll(".xml", ".sedml"), lemsFile.getName(), Format.SBML); List ff = nw.convert(); for(File f : ff) { - System.out.println("Generated sed-ml: " + f.getCanonicalPath()); + System.out.println("Generated SED-ML: " + f.getCanonicalPath()); } } diff --git a/src/main/java/org/neuroml/export/eden/EDENWriter.java b/src/main/java/org/neuroml/export/eden/EDENWriter.java new file mode 100644 index 000000000..e94b9260c --- /dev/null +++ b/src/main/java/org/neuroml/export/eden/EDENWriter.java @@ -0,0 +1,225 @@ +package org.neuroml.export.eden; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.exception.VelocityException; +import org.lemsml.jlems.core.logging.E; +import org.lemsml.jlems.core.logging.MinimalMessageHandler; +import org.lemsml.jlems.core.sim.LEMSException; +import org.lemsml.jlems.core.type.Component; +import org.lemsml.jlems.core.type.Lems; +import org.lemsml.jlems.core.type.Target; +import org.lemsml.jlems.io.util.FileUtil; +import org.neuroml.export.base.ANeuroMLBaseWriter; +import org.neuroml.export.exceptions.GenerationException; +import org.neuroml.export.exceptions.ModelFeatureSupportException; +import org.neuroml.export.utils.Format; +import org.neuroml.export.utils.Utils; +import org.neuroml.export.utils.VelocityUtils; +import org.neuroml.export.utils.support.ModelFeature; +import org.neuroml.export.utils.support.SupportLevelInfo; +import org.neuroml.model.util.NeuroMLException; + +@SuppressWarnings("StringConcatenationInsideStringBufferAppend") +public class EDENWriter extends ANeuroMLBaseWriter +{ + String comm = "#"; + String commPre = "'''"; + String commPost = "'''"; + + boolean nogui = true; + + private final List outputFiles = new ArrayList(); + private File lemsFile = null; + + public EDENWriter(Lems lems, File lemsFile) throws ModelFeatureSupportException, LEMSException, NeuroMLException + { + super(lems, Format.EDEN); + this.lemsFile = lemsFile; + initializeWriter(); + } + + public EDENWriter(Lems lems, File lemsFile, File outputFolder, String outputFileName) throws ModelFeatureSupportException, LEMSException, NeuroMLException + { + super(lems, Format.EDEN, outputFolder, outputFileName); + this.lemsFile = lemsFile; + initializeWriter(); + } + + + @Override + public void setOutputFolder(File outputFolder) + { + super.setOutputFolder(outputFolder); + } + + private void initializeWriter() + { + MinimalMessageHandler.setVeryMinimal(true); + E.setDebug(false); + } + + + @Override + 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.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); + sli.addSupportInfo(format, ModelFeature.MULTI_POPULATION_MODEL, SupportLevelInfo.Level.HIGH); + sli.addSupportInfo(format, ModelFeature.NETWORK_WITH_INPUTS_MODEL, SupportLevelInfo.Level.HIGH); + sli.addSupportInfo(format, ModelFeature.NETWORK_WITH_PROJECTIONS_MODEL, SupportLevelInfo.Level.HIGH); + sli.addSupportInfo(format, ModelFeature.MULTICOMPARTMENTAL_CELL_MODEL, SupportLevelInfo.Level.HIGH); + sli.addSupportInfo(format, ModelFeature.NETWORK_WITH_GAP_JUNCTIONS_MODEL, SupportLevelInfo.Level.HIGH); + sli.addSupportInfo(format, ModelFeature.HH_CHANNEL_MODEL, SupportLevelInfo.Level.HIGH); + sli.addSupportInfo(format, ModelFeature.KS_CHANNEL_MODEL, SupportLevelInfo.Level.HIGH); + } + + @Override + protected void addComment(StringBuilder sb, String comment) + { + if(!comment.contains("\n")) sb.append(comm + comment + "\n"); + else sb.append(commPre + "\n" + comment + "\n" + commPost + "\n"); + } + + public void setNoGui(boolean nogui) + { + this.nogui = nogui; + } + + public boolean isNoGui() + { + return nogui; + } + + + public String getMainScript() throws GenerationException, LEMSException, NeuroMLException, IOException + { + + StringBuilder mainRunScript = new StringBuilder(); + + Target target = lems.getTarget(); + Component simCpt = target.getComponent(); + + addComment(mainRunScript, format + " simulator compliant export for:\n\n" + lems.textSummary(false, false) + "\n\n" + Utils.getHeaderComment(format) + "\n"); + + VelocityUtils.initializeVelocity(); + VelocityContext context = new VelocityContext(); + + try + { + + + context.internalPut("main_lems_file", lemsFile.getAbsolutePath()); + + VelocityEngine ve = VelocityUtils.getVelocityEngine(); + StringWriter sw1 = new StringWriter(); + + ve.evaluate(context, sw1, "LOG", VelocityUtils.getTemplateAsReader(VelocityUtils.edenRunTemplateFile)); + mainRunScript.append(sw1); + + } + catch(VelocityException e) + { + throw new GenerationException("Problem using Velocity template", e); + } + + return mainRunScript.toString(); + + } + + @Override + public List convert() throws GenerationException, IOException + { + String code; + try + { + code = this.getMainScript(); + } + catch (LEMSException ex) + { + throw new GenerationException("Error on generation", ex); + } + catch (NeuroMLException ex) + { + throw new GenerationException("Error on generation", ex); + } + + File outputFile = new File(this.getOutputFolder(), this.getOutputFileName()); + FileUtil.writeStringToFile(code, outputFile); + outputFiles.add(outputFile); + + E.info("Saving main EDEN file to: " + outputFile.getAbsolutePath()); + + return this.outputFiles; + } + + public static void main(String[] args) throws Exception + { + + ArrayList lemsFiles = new ArrayList(); + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex0_IaF.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/LEMS_Spikers.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/hippocampus/CA1_pyramidal_neuron/FergusonEtAl2014-CA1PyrCell/NeuroML2/LEMS_TwoCells.xml")); + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex19a_GapJunctionInstances.xml")); + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex25_MultiComp.xml")); + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex19a_GapJunctionInstances.xml")); + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex14_PyNN.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/IzhikevichModel/NeuroML2/LEMS_SmallNetwork.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/IzhikevichModel/NeuroML2/LEMS_FiveCells.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/IzhikevichModel/NeuroML2/LEMS_2007Cells.xml")); + //lemsFiles.add(new File("../OpenCortex/examples/LEMS_SpikingNet.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/scaling/LEMS_Balanced_0.2.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/showcase/StochasticityShowcase/NeuroML2/LEMS_Inputs.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/LEMS_Spikers.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/showcase/ghk-nernst/NeuroML2/LEMS_nernst_na_k_ca.xml")); + //lemsFiles.add(new File("/home/padraig/git/osb-model-validation/utilities/local_test/netpyneshowcase/NeuroML2/scaling/LEMS_Balanced.xml")); + //lemsFiles.add(new File("/home/padraig/git/osb-model-validation/utilities/local_test/netpyneshowcase/NeuroML2/scaling/LEMS_Balanced_hdf5.xml")); + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex25_MultiComp.xml")); + /* + lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/LEMS_2007One.xml")); + lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/ACnet2/neuroConstruct/generatedNeuroML2/LEMS_TwoCell.xml")); + lemsFiles.add(new File("../neuroConstruct/osb/cerebellum/cerebellar_granule_cell/GranuleCell/neuroConstruct/generatedNeuroML2/LEMS_GranuleCell.xml")); + lemsFiles.add(new File("../OpenCortex/examples/LEMS_SimpleNet.xml")); + lemsFiles.add(new File("../OpenCortex/examples/LEMS_IClamps.xml")); + lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/Thalamocortical/NeuroML2/pythonScripts/netbuild/LEMS_Figure7AeLoSS.xml"));*/ + + //lemsFiles.add(new File("../git/TestHippocampalNetworks/NeuroML2/cells/tests/LEMS_axoaxonic.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/chanDens/LEMS_cck.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/scaling/LEMS_Balanced_0.2.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/scaling/LEMS_Balanced.xml")); + //lemsFiles.add(new File("../OpenCortex/examples/HDF5/LEMS_SpikingNet.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/generic/hodgkin_huxley_tutorial/Tutorial2/NeuroML2/LEMS_HHTutorial.xml")); + lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex5_DetCell.xml")); + //lemsFiles.add(new File("../git/osb-model-validation/utilities/tests/LEMS_NML2_Ex5_DetCell.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/neocortical_pyramidal_neuron/MainenEtAl_PyramidalCell/neuroConstruct/generatedNeuroML2/LEMS_OneComp.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/multiple/PospischilEtAl2008/NeuroML2/cells/FS/LEMS_FS.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/ACnet2/neuroConstruct/generatedNeuroML2/LEMS_ACnet2.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/generic/hodgkin_huxley_tutorial/Tutorial/Source/LEMS_HH_Simulation.xml")); + + for (File lemsFile : lemsFiles) + { + Lems lems = Utils.readLemsNeuroMLFile(lemsFile, false).getLems(); + System.out.println("lems c"+lems.components); + EDENWriter pw = new EDENWriter(lems, lemsFile); + pw.setOutputFolder(lemsFile.getParentFile()); + pw.setOutputFileName(lemsFile.getName().replaceAll(".xml", "_eden.py")); + + List files = pw.convert(); + for (File f : files) + { + System.out.println("Have created: " + f.getAbsolutePath()); + } + + } + } + +} diff --git a/src/main/java/org/neuroml/export/graph/GraphWriter.java b/src/main/java/org/neuroml/export/graph/GraphWriter.java index 2248959b2..33c20317f 100644 --- a/src/main/java/org/neuroml/export/graph/GraphWriter.java +++ b/src/main/java/org/neuroml/export/graph/GraphWriter.java @@ -118,7 +118,8 @@ public String getMainScript() throws GenerationException addComment(main, "GraphViz compliant export for:" + tgtNet.summary() + "\n"); main.append("digraph " + simCpt.getID().replaceAll("-", "_") + " {\n"); - main.append("fontsize=10;\n\n"); + main.append("fontsize=10;\n"); + main.append("overlap=false;\n\n"); if(rankdirLR) main.append("rankdir=\"LR\"\n"); net.append(" node [shape=" + netShape + "]; " + tgtNet.getID() + ";\n"); diff --git a/src/main/java/org/neuroml/export/info/InfoTreeCreator.java b/src/main/java/org/neuroml/export/info/InfoTreeCreator.java index 971c5aeb8..79fd9e30b 100644 --- a/src/main/java/org/neuroml/export/info/InfoTreeCreator.java +++ b/src/main/java/org/neuroml/export/info/InfoTreeCreator.java @@ -133,11 +133,6 @@ else if(cd.getSegment() != null) cellProps.put("Specific capacitance on group " + sc.getSegmentGroup(), scProps); scProps.put("Segment group", sc.getSegmentGroup()); } - else if(sc.getSegment() != null) - { - cellProps.put("Specific capacitance on segment " + sc.getSegment(), scProps); - scProps.put("Segment", sc.getSegment()); - } else { cellProps.put("Specific capacitance", scProps); @@ -156,11 +151,6 @@ else if(sc.getSegment() != null) cellProps.put("Resistivity on group " + res.getSegmentGroup(), resProps); resProps.put("Segment group", res.getSegmentGroup()); } - else if(res.getSegment() != null) - { - cellProps.put("Resistivity on segment " + res.getSegment(), resProps); - resProps.put("Segment", res.getSegment()); - } else { cellProps.put("Resistivity", resProps); diff --git a/src/main/java/org/neuroml/export/netpyne/NetPyNEWriter.java b/src/main/java/org/neuroml/export/netpyne/NetPyNEWriter.java index d21d748dd..04b8aea0e 100644 --- a/src/main/java/org/neuroml/export/netpyne/NetPyNEWriter.java +++ b/src/main/java/org/neuroml/export/netpyne/NetPyNEWriter.java @@ -19,6 +19,7 @@ import org.lemsml.jlems.core.type.Lems; import org.lemsml.jlems.core.type.Target; import org.lemsml.jlems.io.util.FileUtil; +import org.lemsml.jlems.io.IOUtil; import org.neuroml.export.base.ANeuroMLBaseWriter; import org.neuroml.export.exceptions.GenerationException; import org.neuroml.export.exceptions.ModelFeatureSupportException; @@ -127,35 +128,55 @@ public boolean isNoGui() } - public List generateAndRun(boolean nogui, boolean runNrn, int np) throws LEMSException, GenerationException, NeuroMLException, IOException, ModelFeatureSupportException + public List generateAndRun(boolean nogui, boolean runNrn, int np, boolean json) throws LEMSException, GenerationException, NeuroMLException, IOException, ModelFeatureSupportException { List files = convert(); this.setNoGui(true); - if(runNrn) + if(runNrn || json) { E.info("Trying to compile mods in: " + this.getOutputFolder()); ProcessManager.compileFileWithNeuron(this.getOutputFolder(), false); - String commandToExecute; + List commandToExecute = new ArrayList(); + List runAndOrJson = new ArrayList(); + + if (json) + { + runAndOrJson.add("-json"); + }; + if (!runNrn) {runAndOrJson.add("-norun");}; + if (np==1) { - commandToExecute = "python " - + new File(this.getOutputFolder(), this.getOutputFileName()).getCanonicalPath(); + commandToExecute.add("python"); + commandToExecute.add(new File(this.getOutputFolder(), this.getOutputFileName()).getCanonicalPath()); + commandToExecute.addAll(runAndOrJson); } else { File neuronHome = findNeuronHome(); - commandToExecute = "mpiexec -np "+np+" "+ neuronHome.getCanonicalPath() + System.getProperty("file.separator") + "bin" + System.getProperty("file.separator") +"nrniv -mpi " - + new File(this.getOutputFolder(), this.getOutputFileName()).getCanonicalPath(); + + commandToExecute.add("mpiexec"); + commandToExecute.add("-np"); + commandToExecute.add(Integer.toString(np)); + commandToExecute.add(neuronHome.getCanonicalPath() + System.getProperty("file.separator") + "bin" + System.getProperty("file.separator") +"nrniv"); + commandToExecute.add("-mpi"); + commandToExecute.add(new File(this.getOutputFolder(), this.getOutputFileName()).getCanonicalPath()); + + commandToExecute.addAll(runAndOrJson); + //commandToExecute = "mpiexec -np "+np+" "+ neuronHome.getCanonicalPath() + System.getProperty("file.separator") + "bin" + System.getProperty("file.separator") +"nrniv -mpi " + // + new File(this.getOutputFolder(), this.getOutputFileName()).getCanonicalPath() + runAndOrJson; } - E.info("Going to execute command: " + commandToExecute); + E.info("Going to execute thee command: " + commandToExecute); Runtime rt = Runtime.getRuntime(); - Process currentProcess = rt.exec(commandToExecute, null, this.getOutputFolder()); - ProcessOutputWatcher procOutputMain = new ProcessOutputWatcher(currentProcess.getInputStream(), "NRN Output >>"); + String[] commandToExecuteArr = new String[ commandToExecute.size() ]; + commandToExecute.toArray( commandToExecuteArr ); + Process currentProcess = rt.exec(commandToExecuteArr, null, this.getOutputFolder()); + ProcessOutputWatcher procOutputMain = new ProcessOutputWatcher(currentProcess.getInputStream(), "NetPyNE Output >>"); procOutputMain.start(); ProcessOutputWatcher procOutputError = new ProcessOutputWatcher(currentProcess.getErrorStream(), "NRN Error >>"); @@ -167,6 +188,10 @@ public List generateAndRun(boolean nogui, boolean runNrn, int np) throws L { currentProcess.waitFor(); E.info("Exit value for running PyNEURON: " + currentProcess.exitValue()); + if (currentProcess.exitValue()!=0) + { + throw new GenerationException("Exit value for running PyNEURON for NetPyNE: " + currentProcess.exitValue()); + } } catch(InterruptedException e) { @@ -193,7 +218,7 @@ public String getMainScript() throws GenerationException, LEMSException, NeuroML Target target = lems.getTarget(); Component simCpt = target.getComponent(); - addComment(mainRunScript, format + " simulator compliant export for:\n\n" + lems.textSummary(false, false) + "\n\n" + Utils.getHeaderComment(format) + "\n"); + addComment(mainRunScript, format + " simulator compliant export for:\n\n" + lems.textSummary(false, false) + "\n\n" + Utils.getHeaderComment(format) + "\n"); String mainNetworkFile = null; String onlyNmlFile = null; @@ -277,10 +302,18 @@ public String getMainScript() throws GenerationException, LEMSException, NeuroML context.internalPut("main_network_file", mainNetworkFile); + String reportFileOrig = (String) context.internalGet(DLemsKeywords.REPORT_FILE.get()); + if (reportFileOrig!=null) + { + String reportFile = IOUtil.getCompleteReportFileName(reportFileOrig, "NetPyNE", null); + context.internalPut(DLemsKeywords.REPORT_FILE.get(), reportFile); + } + VelocityEngine ve = VelocityUtils.getVelocityEngine(); StringWriter sw1 = new StringWriter(); if (dlemsFile.getName().equals(mainDlemsFile)) { + ve.evaluate(context, sw1, "LOG", VelocityUtils.getTemplateAsReader(VelocityUtils.netpyneRunTemplateFile)); mainRunScript.append(sw1); @@ -293,6 +326,8 @@ public String getMainScript() throws GenerationException, LEMSException, NeuroML addComment(script, format + " simulator compliant export for:\n\n" + lems.textSummary(false, false) + "\n\n" + Utils.getHeaderComment(format) + "\n"); String name = (String) context.internalGet(DLemsKeywords.NAME.get()); + + Component comp = lems.components.getByID(name); //E.info("Component LEMS: " + comp.summary()); String suffix = null; @@ -400,10 +435,11 @@ public static void main(String[] args) throws Exception ArrayList lemsFiles = new ArrayList(); //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex0_IaF.xml")); - lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex5_DetCell.xml")); - lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/LEMS_Spikers.xml")); - lemsFiles.add(new File("../git/GoC_Varied_Inputs/Tests/single_cell/LEMS_sim_test_sim.xml")); - //lemsFiles.add(new File("../neuroConstruct/osb/hippocampus/CA1_pyramidal_neuron/FergusonEtAl2014-CA1PyrCell/NeuroML2/LEMS_TwoCells.xml")); + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex5_DetCell.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/LEMS_Spikers.xml")); + lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/LEMS_HH_Simulation.xml")); + //lemsFiles.add(new File("../git/GoC_Varied_Inputs/Tests/single_cell/LEMS_sim_test_sim.xml")); + //lemsFiles.add(new File("../neuroConstruct/osb/hippocampus/CA1_pyramidal_neuron/FergusonEtAl2014-CA1PyrCell/NeuroML2/LEMS_TwoCells.xml")); //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex19a_GapJunctionInstances.xml")); //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex25_MultiComp.xml")); //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex19a_GapJunctionInstances.xml")); @@ -423,7 +459,7 @@ public static void main(String[] args) throws Exception lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/LEMS_2007One.xml")); lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/ACnet2/neuroConstruct/generatedNeuroML2/LEMS_TwoCell.xml")); lemsFiles.add(new File("../neuroConstruct/osb/cerebellum/cerebellar_granule_cell/GranuleCell/neuroConstruct/generatedNeuroML2/LEMS_GranuleCell.xml")); - lemsFiles.add(new File("../OpenCortex/examples/LEMS_IClamps.xml")); + lemsFiles.add(new File("../OpenCortex/examples/LEMS_IClamps.xml")); lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/Thalamocortical/NeuroML2/pythonScripts/netbuild/LEMS_Figure7AeLoSS.xml"));*/ //lemsFiles.add(new File("../OpenCortex/examples/LEMS_SimpleNet.xml")); @@ -447,7 +483,12 @@ public static void main(String[] args) throws Exception //pw.setRegenerateNeuroMLNet(true); - List files = pw.generateAndRun(true, false, 1); + boolean nogui = true; + boolean runNrn = true; + int np = 1; + boolean json = false; + + List files = pw.generateAndRun(nogui, runNrn, np, json); for (File f : files) { System.out.println("Have created: " + f.getAbsolutePath()); diff --git a/src/main/java/org/neuroml/export/neuron/JSONCellSerializer.java b/src/main/java/org/neuroml/export/neuron/JSONCellSerializer.java index 33293b9fc..be20e12c7 100644 --- a/src/main/java/org/neuroml/export/neuron/JSONCellSerializer.java +++ b/src/main/java/org/neuroml/export/neuron/JSONCellSerializer.java @@ -297,92 +297,107 @@ else if(fract == 0 && segsPar.get(0) == parentId) g.writeEndArray(); g.writeArrayFieldStart("groups"); - boolean foundAll = false; + /* Convert all segment groups. + * Note that the "all" segment group/section list id is reserved. + * We use it to keep a list of all segments/sections. + * A validation step will check to see if the "all" group does have all segments, and throw an error if not. + */ for(SegmentGroup grp : morph.getSegmentGroup()) { - if(!grp.getId().equals("all")) // I'll calculate this here... + /* Do not handle it here, we populate it with all segments later */ + if(grp.getId().equals("all")) { - if(!(foundNeuroLexFlags && CellUtils.isUnbranchedNonOverlapping(grp))) - { - g.writeStartObject(); - g.writeStringField("name", grp.getId()); + continue; + } + if(!(foundNeuroLexFlags && CellUtils.isUnbranchedNonOverlapping(grp))) + { + g.writeStartObject(); + g.writeStringField("name", grp.getId()); - if(!grp.getMember().isEmpty()) + if(!grp.getMember().isEmpty()) + { + g.writeArrayFieldStart("segments"); + for(Member m : grp.getMember()) + { + g.writeString(idsVsNames.get(m.getSegment())); + } + g.writeEndArray(); + } + if(!grp.getInclude().isEmpty()) + { + g.writeArrayFieldStart("groups"); + for(org.neuroml.model.Include inc : grp.getInclude()) + { + boolean isSection = CellUtils.isUnbranchedNonOverlapping(namesVsSegmentGroups.get(inc.getSegmentGroup())); + if(!isSection) { - g.writeArrayFieldStart("segments"); - for(Member m : grp.getMember()) - { - g.writeString(idsVsNames.get(m.getSegment())); - } - g.writeEndArray(); + g.writeString(inc.getSegmentGroup()); } - if(!grp.getInclude().isEmpty()) + } + g.writeEndArray(); + g.writeArrayFieldStart("sections"); + for(org.neuroml.model.Include inc : grp.getInclude()) + { + boolean isSection = CellUtils.isUnbranchedNonOverlapping(namesVsSegmentGroups.get(inc.getSegmentGroup())); + if(isSection) { - g.writeArrayFieldStart("groups"); - for(org.neuroml.model.Include inc : grp.getInclude()) - { - boolean isSection = CellUtils.isUnbranchedNonOverlapping(namesVsSegmentGroups.get(inc.getSegmentGroup())); - if(!isSection) - { - g.writeString(inc.getSegmentGroup()); - } - } - g.writeEndArray(); - g.writeArrayFieldStart("sections"); - for(org.neuroml.model.Include inc : grp.getInclude()) - { - boolean isSection = CellUtils.isUnbranchedNonOverlapping(namesVsSegmentGroups.get(inc.getSegmentGroup())); - if(isSection) - { - g.writeString(inc.getSegmentGroup()); - } - } - g.writeEndArray(); + g.writeString(inc.getSegmentGroup()); } - // System.out.println("+++ " +grp.getInhomogeneousParameter()); - // System.out.println("-- " +ChannelDensity.class.getSimpleName()); - if(!grp.getInhomogeneousParameter().isEmpty()) + } + g.writeEndArray(); + } + // System.out.println("+++ " +grp.getInhomogeneousParameter()); + // System.out.println("-- " +ChannelDensity.class.getSimpleName()); + if(!grp.getInhomogeneousParameter().isEmpty()) + { + g.writeArrayFieldStart("inhomogeneousParameters"); + for(InhomogeneousParameter ih : grp.getInhomogeneousParameter()) + { + g.writeStartObject(); + g.writeStringField("id", ih.getId()); + g.writeStringField("variable", ih.getVariable()); + inhomogeneousParametersVsVariables.put(ih.getId(), ih.getVariable()); + g.writeStringField("metric", ih.getMetric().value()); + if(ih.getProximal() != null) { - g.writeArrayFieldStart("inhomogeneousParameters"); - for(InhomogeneousParameter ih : grp.getInhomogeneousParameter()) - { - g.writeStartObject(); - g.writeStringField("id", ih.getId()); - g.writeStringField("variable", ih.getVariable()); - inhomogeneousParametersVsVariables.put(ih.getId(), ih.getVariable()); - g.writeStringField("metric", ih.getMetric().value()); - if(ih.getProximal() != null) - { - g.writeStringField("proximalTranslationStart", ih.getProximal().getTranslationStart() + ""); - } - if(ih.getDistal() != null) - { - g.writeStringField("distalNormalizationEnd", ih.getDistal().getNormalizationEnd() + ""); - } - g.writeEndObject(); - } - g.writeEndArray(); + g.writeStringField("proximalTranslationStart", ih.getProximal().getTranslationStart() + ""); } - - g.writeEndObject(); + if(ih.getDistal() != null) + { + g.writeStringField("distalNormalizationEnd", ih.getDistal().getNormalizationEnd() + ""); + } + g.writeEndObject(); + } + g.writeEndArray(); } + + g.writeEndObject(); } } - if(!foundAll) + + /* Create the "all" section list that contains all sections */ + g.writeStartObject(); + g.writeStringField("name", "all"); + g.writeArrayFieldStart("sections"); + + ArrayList includedSections = new ArrayList(); + for(Segment seg : morph.getSegment()) { - g.writeStartObject(); - g.writeStringField("name", "all"); - g.writeArrayFieldStart("sections"); - for(Segment seg : morph.getSegment()) - { - String name = nh.getNrnSectionName(seg); + String name = nh.getNrnSectionName(seg); + if (includedSections.contains(name)) { + continue; + } + else { + System.out.println("Adding segment: " + name); g.writeString(name); + includedSections.add(name); } - g.writeEndArray(); - g.writeEndObject(); - } g.writeEndArray(); + g.writeEndObject(); + + /* groups */ + g.writeEndArray(); IntracellularProperties ip = null; MembraneProperties mp = null; diff --git a/src/main/java/org/neuroml/export/neuron/LEMSQuantityPathNeuron.java b/src/main/java/org/neuroml/export/neuron/LEMSQuantityPathNeuron.java index 9c024d86b..e44ee66c9 100644 --- a/src/main/java/org/neuroml/export/neuron/LEMSQuantityPathNeuron.java +++ b/src/main/java/org/neuroml/export/neuron/LEMSQuantityPathNeuron.java @@ -32,11 +32,11 @@ public class LEMSQuantityPathNeuron extends LEMSQuantityPath Lems lems = null; Component popComp = null; - public LEMSQuantityPathNeuron(String q, - String s, - Component targetComp, - HashMap compMechNamesHoc, - ArrayList popsOrComponents, + public LEMSQuantityPathNeuron(String q, + String s, + Component targetComp, + HashMap compMechNamesHoc, + ArrayList popsOrComponents, HashMap compIdsVsCells, HashMap hocRefsVsInputs, Lems lems) throws ContentError @@ -60,8 +60,8 @@ public LEMSQuantityPathNeuron(String q, } } } - public LEMSQuantityPathNeuron(String q, - String s, + public LEMSQuantityPathNeuron(String q, + String s, Lems lems) throws ContentError { super(q, s); @@ -118,7 +118,7 @@ private static Exposure getExposure(Component c, String path) throws ContentErro } } - + public Dimension getDimensionOfVariableOnCellInPopComp(String[] variableParts, Component popComp) throws ContentError { String path = getVariablePathInPopComp(variableParts, Type.VAR_IN_CELL_IN_POP_LIST); @@ -128,7 +128,7 @@ public Dimension getDimensionOfVariableOnCellInPopComp(String[] variableParts, C return lems.getDimensions().getByName("current"); } return getExposure(popComp, path).getDimension(); - + } public Dimension getDimension() throws ContentError, NeuroMLException @@ -164,12 +164,12 @@ public String getNeuronVariableLabel() throws ContentError } } - - private String convertToNeuronVariable() throws ContentError + + private String convertToNeuronVariable() throws ContentError { return convertToNeuronVariable(variableParts, popComp); } - + public static String convertToNeuronVariable(String[] variableParts, Component popComp) throws ContentError { HashMap topSubstitutions = new HashMap(); @@ -211,7 +211,7 @@ else if (var.equals("iDensity")) { if (c.getID().equals(channelDensId)) { - var = "i" + c.getStringValue("ion"); + var = "i__" + c.getStringValue("ionChannel") + "_" + c.getStringValue("ionChannel"); } } } @@ -245,8 +245,8 @@ else if (var.equals("iDensity")) return var; } - - + + public String getSynapseType() { if (!isVariableOnSynapse()) @@ -255,12 +255,12 @@ public String getSynapseType() } String var = getVariable(); - + String[] synInfo = var.split(":"); return synInfo[1]; } - + public int getSynapseIndex() { if (!isVariableOnSynapse()) @@ -274,7 +274,7 @@ public int getSynapseIndex() return index; } - + public String getVariableOnSyn() { if (!isVariableOnSynapse()) @@ -288,7 +288,7 @@ public String getVariableOnSyn() } - + public String getPathforVariableOnSyn() { if (!isVariableOnSynapse()) @@ -300,7 +300,7 @@ public String getPathforVariableOnSyn() return var.substring(var.indexOf("/") + 1); } - + public boolean valid() { try @@ -318,11 +318,11 @@ public boolean valid() return true; } - - + + public String getNeuronVariableReference() throws ContentError, NeuroMLException { - try + try { if (myType == Type.VAR_IN_SINGLE_COMP) { @@ -338,11 +338,11 @@ else if (isVariableOnSynapse()) } else { - if (popComp != null && - (popComp.getComponentType().isOrExtends(NeuroMLElements.CELL_COMP_TYPE) || - ((popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_CELL_CAP_COMP_TYPE) || - popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_IAF_CELL)|| - popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) && + if (popComp != null && + (popComp.getComponentType().isOrExtends(NeuroMLElements.CELL_COMP_TYPE) || + ((popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_CELL_CAP_COMP_TYPE) || + popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_IAF_CELL)|| + popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) && convertToNeuronVariable().equals(NRNUtils.NEURON_VOLTAGE)))) { if (compIdsVsCells.containsKey(popComp.getID())) @@ -351,7 +351,7 @@ else if (isVariableOnSynapse()) NamingHelper nh = new NamingHelper(cell); Segment segment = CellUtils.getSegmentWithId(cell, segmentId); String varInst = nh.getNrnSectionName(segment); - + float fract; if (cell.getMorphology().getSegment().size() == 1) { @@ -369,7 +369,7 @@ else if (!CellUtils.hasSegmentGroup(cell, varInst) && segment.getName().equals(v String varRef; String possibleInputRef = getPopulationArray() + "[" + populationIndex + "]." + varInst +":"+ variableParts[0]; - + if (hocRefsVsInputs.containsKey(possibleInputRef)) { varRef = hocRefsVsInputs.get(possibleInputRef)+ "." + variableParts[1]; @@ -384,7 +384,7 @@ else if (!CellUtils.hasSegmentGroup(cell, varInst) && segment.getName().equals(v { String nrnVar = convertToNeuronVariable(); //String possibleInputRef = getPopulationArray() + "[" + populationIndex + "]:"+ variableParts[0]; - + String varRef = getPopulation() + "[" + populationIndex + "]." + nrnVar; if (nrnVar.equals(NRNUtils.NEURON_VOLTAGE)) @@ -427,16 +427,16 @@ public String toString() ref = "=== Unable to determine reference: " + ex; } - ref += super.toString() + ref += super.toString() + "\n ** Neuron ref: " + ref - + "\n popsOrComponents: " + popsOrComponents - + "\n targetComp: " + targetComp + + "\n popsOrComponents: " + popsOrComponents + + "\n targetComp: " + targetComp + "\n popComp: " + popComp + "\n hocRefsVsInputs: " + hocRefsVsInputs; - + if (this.isVariableOnSynapse()) { - ref + ref +="\n Synapse type: " + this.getSynapseType() + "\n Synapse index: " + this.getSynapseIndex() + "\n Synapse var: " + this.getVariableOnSyn(); @@ -447,7 +447,7 @@ public String toString() public static void main(String[] args) throws Exception { HashMap compMechNamesHoc = new HashMap(); - + compMechNamesHoc.put("fnPop1[i]", "m_fitzHughNagumoCell[i]"); ArrayList popsOrComponents = new ArrayList(); ArrayList paths = new ArrayList(); @@ -459,9 +459,9 @@ public static void main(String[] args) throws Exception System.out.println("\n--------\n" + l1); if (!l1.valid()) throw new Exception("Should be valid"); } - + compMechNamesHoc = new HashMap(); - + paths = new ArrayList(); paths.add("hhpop/0/hhneuron/v"); paths.add("hhpop/0/hhneuron/biophysics/membraneProperties/kChans/gDensity"); @@ -473,24 +473,24 @@ public static void main(String[] args) throws Exception paths.add("hhpop/0/hhneuron/0/v"); paths.add("hhpop/0/hhneuron/0/synapses:AMPA:0/g"); paths.add("hhpop/0/hhneuron/0/synapses:bc_syn:0/g"); - + Lems lems = Utils.readLemsNeuroMLFile(new File("../neuroConstruct/osb/generic/hodgkin_huxley_tutorial/Tutorial2/NeuroML2/LEMS_HHTutorial.xml")).getLems(); NeuroMLConverter nmlc = new NeuroMLConverter(); NeuroMLDocument nmldoc = nmlc.loadNeuroML(new File("../neuroConstruct/osb/generic/hodgkin_huxley_tutorial/Tutorial2/NeuroML2/HHTutorial.net.nml"), true); - + Component hhnet = lems.getComponent("HHTutorial"); popsOrComponents = hhnet.getChildrenAL("populations"); Cell c = nmldoc.getCell().get(0); HashMap compIdsVsCells = new HashMap(); HashMap hocRefsVsInputs = new HashMap(); hocRefsVsInputs.put("a_hhpop[0].soma:IClamp","Input_0_0"); - + for (String path : paths) { LEMSQuantityPathNeuron l1 = new LEMSQuantityPathNeuron(path, "1", hhnet, compMechNamesHoc, popsOrComponents, compIdsVsCells, hocRefsVsInputs, lems); System.out.println("\n===================\n" + l1); if (!l1.valid()) throw new Exception("Should be valid"); - + } } diff --git a/src/main/java/org/neuroml/export/neuron/NRNUtils.java b/src/main/java/org/neuroml/export/neuron/NRNUtils.java index 6da5883ea..d2da2979c 100644 --- a/src/main/java/org/neuroml/export/neuron/NRNUtils.java +++ b/src/main/java/org/neuroml/export/neuron/NRNUtils.java @@ -37,9 +37,9 @@ public class NRNUtils implements UnitConverter final static String V_CURRENT_SUFFIX = "_I"; final static String RATE_PREFIX = "rate_"; final static String REGIME_PREFIX = "regime_"; - final static String V_COPY_PREFIX = "copy_"; - - final static String[] NON_NRN_STATE_VARS + //final static String V_COPY_PREFIX = "copy_"; + + final static String[] NON_NRN_STATE_VARS = new String[]{"weightFactor","isi","nextIsi","lastSpikeTime","nextSpikeTemp","nextSpike"}; final static String caConc = "caConc"; @@ -51,6 +51,10 @@ public class NRNUtils implements UnitConverter static final int commentOffset = 40; + static final String LEN_UNIT = "cm"; + static final float LEN_CONVERSION = 1e2f; + + static final String generalUnits = "\n(nA) = (nanoamp)\n" + "(uA) = (microamp)\n" + "(mA) = (milliamp)\n" @@ -58,11 +62,13 @@ public class NRNUtils implements UnitConverter + "(mV) = (millivolt)\n" + "(mS) = (millisiemens)\n" + "(uS) = (microsiemens)\n" + + "(nF) = (nanofarad)\n" + "(molar) = (1/liter)\n" + "(kHz) = (kilohertz)\n" + "(mM) = (millimolar)\n" + "(um) = (micrometer)\n" + "(umol) = (micromole)\n" + + "(pC) = (picocoulomb)\n" + "(S) = (siemens)\n"; static final String ghkUnits = ": bypass nrn default faraday const\n" + "FARADAY = 96485.3 (coulomb)\n" + "R = (k-mole) (joule/degC)\n"; @@ -82,7 +88,7 @@ public class NRNUtils implements UnitConverter + " }else{\n" + " efun = z/(exp(z) - 1)\n" + " }\n" + "}\n"; - + static final String ghk2FunctionDefs = "\nFUNCTION ghk2(v(mV), ci(mM), co(mM)) (mV) {\n" + " LOCAL nu,f\n" + "\n" + @@ -170,7 +176,7 @@ public class NRNUtils implements UnitConverter + "" + "" + "\n"; - + static final String heavisideFunctionDefs = "\n: The Heaviside step function\nFUNCTION H(x) {\n" + " \n" + " if (x < 0) { H = 0 }\n" @@ -203,15 +209,15 @@ public static String getSafeName(String id) return id + suffix; } - protected static String checkCommentLineLength(String comment) + protected static String checkCommentLineLength(String comment) { int maxLength = 500; - if (comment.length()<=maxLength) + if (comment.length()<=maxLength) return comment; else return comment.substring(0,maxLength-3)+"..."; } - + protected static String getStateVarName(String sv) { if (sv.equals(NRNUtils.NEURON_VOLTAGE)) @@ -228,11 +234,11 @@ protected static String checkForBinaryOperators(String expr) { return expr.replace("\\.gt\\.", ">").replace("\\.geq\\.", ">=").replace("\\.lt\\.", "<").replace("\\.leq\\.", "<=").replace("\\.and\\.", "&&").replace("\\.neq\\.", "!="); } - + protected static float getThreshold(Component comp, Lems lems) throws ParseError, ContentError, LEMSException { float threshold = 0; - if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_IAF_CAP_CELL) || + if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_IAF_CAP_CELL) || comp.getComponentType().isOrExtends(NeuroMLElements.BASE_IAF_CELL)) { threshold = NRNUtils.convertToNeuronUnits(comp.getStringValue("thresh"), lems); @@ -241,7 +247,7 @@ else if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) { if ( (comp.getComponentType().isOrExtends("EIF_cond_alpha_isfa_ista") || comp.getComponentType().isOrExtends("EIF_cond_exp_isfa_ista"))) { - if (NRNUtils.convertToNeuronUnits(comp.getStringValue("delta_T"), lems)==0 ) + if (NRNUtils.convertToNeuronUnits(comp.getStringValue("delta_T"), lems)==0 ) { threshold = NRNUtils.convertToNeuronUnits(comp.getStringValue("v_thresh"), lems); } @@ -342,7 +348,7 @@ else if (dimensionName.equals("conductance")) } else if (dimensionName.equals("capacitance")) { - return "(microfarads)"; + return "(nF)"; } else if (dimensionName.equals("specificCapacitance")) { @@ -362,7 +368,7 @@ else if (dimensionName.equals("current")) } else if (dimensionName.equals("currentDensity")) { - return "(nA / um2)"; + return "(nA / cm2)"; } else if (dimensionName.equals("current_per_time")) { @@ -370,19 +376,23 @@ else if (dimensionName.equals("current_per_time")) } else if (dimensionName.equals("conductanceDensity")) { - return "(uS / um2)"; + return "(uS / cm2)"; + } + else if (dimensionName.equals("conductanceDensity_hoc")) + { + return "(S / cm2)"; } else if (dimensionName.equals("length")) { - return "(um)"; + return "("+LEN_UNIT+")"; } else if (dimensionName.equals("area")) { - return "(um2)"; + return "("+LEN_UNIT+"2)"; } else if (dimensionName.equals("volume")) { - return "(um3)"; + return "("+LEN_UNIT+"3)"; } else if (dimensionName.equals("resistivity")) { @@ -398,7 +408,7 @@ else if (dimensionName.equals("concentration")) } else if (dimensionName.equals("charge_per_mole")) { - return "(C / umol)"; + return "(pC / umol)"; } else if (dimensionName.equals("temperature")) { @@ -406,11 +416,11 @@ else if (dimensionName.equals("temperature")) } else if (dimensionName.equals("idealGasConstantDims")) { - return "(millijoule / K / umol)"; + return "(femtojoule / K / umol)"; } else if (dimensionName.equals("rho_factor")) { - return "(mM m2 /A /s)"; + return "(umol / cm / nA / ms)"; } else if (dimensionName.equals("conductance_per_voltage")) { @@ -431,7 +441,7 @@ protected static float convertToNeuronUnits(String neuromlQuantity, Lems lems) t DimensionalQuantity dq = QuantityReader.parseValue(neuromlQuantity, lems.getUnits()); return convertToNeuronUnits((float)dq.getDoubleValue(), dq.getDimension().getName()); } - + @Override public float convert(float siValue, String dimensionName) throws LEMSException { @@ -443,7 +453,7 @@ protected static float convertToNeuronUnits(float siVal, String dimensionName) t BigDecimal factor = new BigDecimal(getNeuronUnitFactor(dimensionName)); BigDecimal newValB = new BigDecimal(siVal+""); newValB = newValB.multiply(factor); - + float newVal = newValB.floatValue(); //System.out.println("f "+factor+" val "+siVal+" new "+newVal+"; new "+newValB+"; dim "+dimensionName); return newVal; @@ -474,7 +484,7 @@ else if (dimensionName.equals("conductance")) } else if (dimensionName.equals("capacitance")) { - return 1e6f; + return 1e9f; } else if (dimensionName.equals("specificCapacitance")) { @@ -490,7 +500,7 @@ else if (dimensionName.equals("current")) } else if (dimensionName.equals("currentDensity")) { - return 1e-3f; + return 0.1f; } else if (dimensionName.equals("current_per_time")) { @@ -498,7 +508,11 @@ else if (dimensionName.equals("current_per_time")) } else if (dimensionName.equals("conductanceDensity")) { - return 1e-6f; + return 1e2f; + } + else if (dimensionName.equals("conductanceDensity_hoc")) + { + return 1e-4f; } else if (dimensionName.equals("time")) { @@ -506,15 +520,15 @@ else if (dimensionName.equals("time")) } else if (dimensionName.equals("length")) { - return 1000000f; + return LEN_CONVERSION; } else if (dimensionName.equals("area")) { - return 1e12f; + return LEN_CONVERSION * LEN_CONVERSION; } else if (dimensionName.equals("volume")) { - return 1e18f; + return LEN_CONVERSION * LEN_CONVERSION * LEN_CONVERSION; } else if (dimensionName.equals("resistance")) { @@ -530,15 +544,15 @@ else if (dimensionName.equals("concentration")) } else if (dimensionName.equals("charge_per_mole")) { - return 1e-6f; + return 1e6f; } else if (dimensionName.equals("idealGasConstantDims")) { - return 0.001f; + return 1e9f; } else if (dimensionName.equals("rho_factor")) { - return 1f; + return 1e-8f; } else if (dimensionName.equals("conductance_per_voltage")) { @@ -561,12 +575,16 @@ protected static String getDerivativeUnit(String dimensionName) { return "(/ms)"; } + if (dimensionName.equals("voltage")) // special case... for rate to calculate neuron voltage/current from abstract cell + { + return "(mV/ms)"; + } else { return unit.replaceAll("\\)", "/ms)"); } } - + public static boolean isPlottingSavingSynVariables(Component simCpt, boolean nogui) { boolean ipssv = false; @@ -626,13 +644,13 @@ public static boolean isPlottingSavingSynVariables(Component simCpt, boolean nog } return ipssv; } - - + + public static void main(String args[]) throws LEMSException { NRNUtils nu = new NRNUtils(); float f = 2.5e-5f; - + System.out.println("Converting "+f+" to "+nu.convert(f, "none")); System.out.println("Converting "+f+" to "+NRNUtils.convertToNeuronUnits(f, "none")); System.out.println("Converting "+f+" to "+nu.convert(f, "voltage")); @@ -640,7 +658,7 @@ public static void main(String args[]) throws LEMSException System.out.println("Converting "+f+" to "+NRNUtils.convertToNeuronUnits(f, "voltage")); System.out.println("Converting "+f+" to "+NRNUtils.convertToNeuronUnits(f, "time")); System.out.println("Converting "+f+" to "+NRNUtils.convertToNeuronUnits(f, "conductance")); - + } diff --git a/src/main/java/org/neuroml/export/neuron/NeuronWriter.java b/src/main/java/org/neuroml/export/neuron/NeuronWriter.java index 88e38cb11..17f5c541d 100644 --- a/src/main/java/org/neuroml/export/neuron/NeuronWriter.java +++ b/src/main/java/org/neuroml/export/neuron/NeuronWriter.java @@ -34,6 +34,7 @@ import org.lemsml.jlems.core.type.Property; import org.lemsml.jlems.core.type.Requirement; import org.lemsml.jlems.core.type.Target; +import org.lemsml.jlems.core.type.Meta; import org.lemsml.jlems.core.type.dynamics.Case; import org.lemsml.jlems.core.type.dynamics.ConditionalDerivedVariable; import org.lemsml.jlems.core.type.dynamics.DerivedVariable; @@ -49,6 +50,7 @@ import org.lemsml.jlems.core.type.dynamics.Transition; import org.lemsml.jlems.core.type.simulation.EventWriter; import org.lemsml.jlems.io.util.FileUtil; +import org.lemsml.jlems.io.IOUtil; import org.neuroml.export.base.ANeuroMLBaseWriter; import org.neuroml.export.exceptions.GenerationException; import org.neuroml.export.exceptions.ModelFeatureSupportException; @@ -83,9 +85,9 @@ public class NeuronWriter extends ANeuroMLBaseWriter boolean nogui = false; static boolean debug = false; - - // if false, generate populations etc. in order found in LEMS/NeuroML (hopefully) - boolean generateAlphabetical = false; + + // if false, generate populations etc. in order found in LEMS/NeuroML (hopefully) + boolean generateAlphabetical = false; public static final String NEURON_HOME_ENV_VAR = "NEURON_HOME"; @@ -98,13 +100,13 @@ public class NeuronWriter extends ANeuroMLBaseWriter private final HashMap popIdsVsComps = new HashMap(); private final HashMap convertedCells = new HashMap(); - + private final String bIndent = " "; - - private boolean parallelMode = false; // Some of the mod files etc. will have to be slightly different for Parallel NEURON - + + private boolean parallelMode = false; // Some of the mod files etc. will have to be slightly different for Parallel NEURON + private static int MAX_LENGTH_LINE_MOD_FILE = 350; - + private final HashMap hocRefsVsInputs = new HashMap(); public enum ChannelConductanceOption @@ -158,7 +160,7 @@ public List generateAndRun(boolean nogui, boolean compileMods, boolean run { if (compileMods) { - E.info("Trying to compile mods in: " + this.getOutputFolder()); + E.info("Trying to compile all the mods in: " + this.getOutputFolder()); boolean complied = ProcessManager.compileFileWithNeuron(this.getOutputFolder(), false); @@ -179,40 +181,50 @@ public List generateAndRun(boolean nogui, boolean compileMods, boolean run if (run) { File neuronHome = findNeuronHome(); - + String nrncmd = nogui ? "nrniv" : "nrngui"; - String fullPath = new File(this.getOutputFolder(), this.getOutputFileName()).getCanonicalPath(); - - String commandToExecute = neuronHome.getCanonicalPath() + System.getProperty("file.separator") + "bin" + System.getProperty("file.separator") + nrncmd + " -python " - + fullPath; - + String fullPath = new File(this.getOutputFolder(), this.getOutputFileName()).getCanonicalPath(); + + List commandToExecute = new ArrayList(); + + + commandToExecute.add(neuronHome.getCanonicalPath() + System.getProperty("file.separator") + "bin" + System.getProperty("file.separator") + nrncmd); + commandToExecute.add("-python"); + commandToExecute.add(fullPath); + + if (nogui && !useNrnivForNoGui) { - commandToExecute = "python " + fullPath; + commandToExecute.add("python"); + commandToExecute.add(fullPath); } Runtime rt = Runtime.getRuntime(); - Process currentProcess = rt.exec(commandToExecute, null, this.getOutputFolder()); + //Process currentProcess = rt.exec(commandToExecute, null, this.getOutputFolder()); + String[] commandToExecuteArr = new String[ commandToExecute.size() ]; + commandToExecute.toArray( commandToExecuteArr ); + Process currentProcess = rt.exec(commandToExecuteArr, null, this.getOutputFolder()); + ProcessOutputWatcher procOutputMain = new ProcessOutputWatcher(currentProcess.getInputStream(), "NRN Output >>"); procOutputMain.start(); ProcessOutputWatcher procOutputError = new ProcessOutputWatcher(currentProcess.getErrorStream(), "NRN Error >>"); procOutputError.start(); - E.info("Have successfully executed command: " + commandToExecute); + E.info("Have successfully executed NEURON command: " + commandToExecute); try { currentProcess.waitFor(); E.info("Exit value for running NEURON: " + currentProcess.exitValue()); - String err = "Error, exit value from running "+fullPath - +" in NEURON: "+currentProcess.exitValue()+"\n"; - + String err = "Error, exit value from running this command: ["+commandToExecute + +"] in NEURON: "+currentProcess.exitValue()+"\n"; + err += Utils.sysEnvInfo(" "); if (currentProcess.exitValue()!=0) throw new NeuroMLException(err); - + } catch(InterruptedException e) { @@ -229,7 +241,7 @@ protected void addComment(StringBuilder sb, String comment) { addComment(sb, comment, ""); } - + protected void addComment(StringBuilder sb, String comment, String indent) { if(!comment.contains("\n")) @@ -266,8 +278,8 @@ public void setGenerateAlphabetical(boolean generateAlphabetical) { this.generateAlphabetical = generateAlphabetical; } - - + + public List generateMainScriptAndMods() throws LEMSException, GenerationException, NeuroMLException { @@ -315,10 +327,9 @@ public String getMainScript() throws GenerationException, NeuroMLException main.append("h(\"objref p\")\n"); main.append("h(\"p = new PythonObject()\")\n\n"); - - Target target = lems.getTarget(); + Target target = lems.getTarget(); Component simCpt = target.getComponent(); String len = simCpt.getStringValue("length"); @@ -329,33 +340,64 @@ public String getMainScript() throws GenerationException, NeuroMLException len = "" + Float.parseFloat(len) * 1000; } - String dt = simCpt.getStringValue("step"); - dt = dt.replaceAll("ms", "").trim(); - if(dt.indexOf("s") > 0) + /* cvode usage: + * https://nrn.readthedocs.io/en/latest/hoc/simctrl/cvode.html + * - we do not currently support the local variable time step method + */ + boolean nrn_cvode = false; + String dt = "0.01"; + /* defaults from NEURON */ + String abs_tol = "None"; + String rel_tol = "None"; + LemsCollection metas = simCpt.metas; + for(Meta m : metas) { - dt = dt.replaceAll("s", "").trim(); - dt = "" + Float.parseFloat(dt) * 1000; + HashMap attributes = m.getAttributes(); + if (attributes.getOrDefault("for", "").equals("neuron")) + { + if (attributes.getOrDefault("method", "").equals("cvode")) + { + nrn_cvode = true; + abs_tol = attributes.getOrDefault("abs_tolerance", abs_tol); + rel_tol = attributes.getOrDefault("rel_tolerance", rel_tol); + E.info("CVode with abs_tol="+abs_tol+" , rel_tol="+rel_tol+" selected for NEURON simulation"); + } + } + } - - + + if (nrn_cvode == false) + { + dt = simCpt.getStringValue("step"); + dt = dt.replaceAll("ms", "").trim(); + if(dt.indexOf("s") > 0) + { + dt = dt.replaceAll("s", "").trim(); + dt = "" + Float.parseFloat(dt) * 1000; + } + } + main.append("class NeuronSimulation():\n\n"); int seed = DLemsWriter.DEFAULT_SEED; if (simCpt.hasStringValue("seed")) seed = Integer.parseInt(simCpt.getStringValue("seed")); - - main.append(" def __init__(self, tstop, dt, seed="+seed+"):\n\n"); - + + main.append(" def __init__(self, tstop, dt=None, seed="+seed+", abs_tol=None, rel_tol=None):\n\n"); + Component targetComp = simCpt.getRefComponents().get("target"); - + main.append(bIndent+"print(\"\\n Starting simulation in NEURON of %sms generated from NeuroML2 model...\\n\"%tstop)\n\n"); main.append(bIndent+"self.setup_start = time.time()\n"); main.append(bIndent+"self.seed = seed\n"); - + main.append(bIndent+"self.abs_tol = abs_tol\n"); + main.append(bIndent+"self.rel_tol = rel_tol\n"); + if (target.reportFile!=null) { main.append(bIndent+"import socket\n"); - main.append(bIndent+"self.report_file = open('"+target.reportFile+"','w')\n"); + String reportFile = IOUtil.getCompleteReportFileName(target.reportFile, "NEURON", null); + main.append(bIndent+"self.report_file = open('"+reportFile+"','w')\n"); main.append(bIndent+"print('Simulator version: %s'%h.nrnversion())\n"); main.append(bIndent+"self.report_file.write('# Report of running simulation with %s\\n'%h.nrnversion())\n"); main.append(bIndent+"self.report_file.write('Simulator=NEURON\\n')\n"); @@ -366,9 +408,9 @@ public String getMainScript() throws GenerationException, NeuroMLException main.append(bIndent+"self.report_file.write('NeuroMLExportVersion="+Utils.ORG_NEUROML_EXPORT_VERSION+"\\n')\n"); main.append(bIndent+"self.report_file.write('SimulationSeed=%s\\n'%self.seed)\n"); main.append(bIndent+"self.report_file.write('Hostname=%s\\n'%socket.gethostname())\n"); - + } - + main.append(bIndent+"self.randoms = []\n"); main.append(bIndent+"self.next_global_id = 0 # Used in Random123 classes for elements using random(), etc. \n\n"); main.append(bIndent+"self.next_spiking_input_id = 0 # Used in Random123 classes for elements using random(), etc. \n\n"); @@ -408,7 +450,7 @@ public String getMainScript() throws GenerationException, NeuroMLException String popName; int number; Component popComp; - + HashMap locations = new HashMap(); HashMap locationStrs = new HashMap(); @@ -433,14 +475,14 @@ else if(popsOrComponent.getComponentType().getName().equals(NeuroMLElements.POPU { number++; Component loc = instance.getChild(NeuroMLElements.LOCATION); - + String location = "("+Float.parseFloat(loc.getAttributeValue(NeuroMLElements.LOCATION_X)) +", "+Float.parseFloat(loc.getAttributeValue(NeuroMLElements.LOCATION_Y)) +", "+Float.parseFloat(loc.getAttributeValue(NeuroMLElements.LOCATION_Z))+")"; - + String locationStr = "("+Float.parseFloat(loc.getAttributeValue(NeuroMLElements.LOCATION_X)) +", "+Float.parseFloat(loc.getAttributeValue(NeuroMLElements.LOCATION_Y)) - +" + XXX, "+Float.parseFloat(loc.getAttributeValue(NeuroMLElements.LOCATION_Z))+", 10)"; + +" + HALF_LENGTH, "+Float.parseFloat(loc.getAttributeValue(NeuroMLElements.LOCATION_Z))+", DIAMETER)"; locations.put(Integer.parseInt(instance.getID()), location); locationStrs.put(Integer.parseInt(instance.getID()), locationStr); @@ -471,7 +513,7 @@ else if(popsOrComponent.getComponentType().getName().equals(NeuroMLElements.POPU { Cell cell = getCellFromComponent(popComp); - + IntracellularProperties ip; if (convertedCells.containsKey(popComp.id)) { @@ -483,11 +525,11 @@ else if(popsOrComponent.getComponentType().getName().equals(NeuroMLElements.POPU convertedCells.put(popComp.id, ip); } NamingHelper nh = new NamingHelper(cell); - + String cellName = popComp.getID(); String fileName = cellName + ".hoc"; - - + + for (Species species: ip.getSpecies()) { float internal = NRNUtils.convertToNeuronUnits(Utils.getMagnitudeInSI(species.getInitialConcentration()), "concentration"); @@ -499,7 +541,7 @@ else if(popsOrComponent.getComponentType().getName().equals(NeuroMLElements.POPU main.append(bIndent+"h(\"" + species.getIon() + "o0_" + species.getIon() + "_ion = " + external + "\")\n\n"); } - + StringBuilder popInfo = new StringBuilder(); popInfo.append(bIndent+"h.load_file(\"" + fileName + "\")\n"); @@ -550,36 +592,46 @@ else if(popsOrComponent.getComponentType().getName().equals(NeuroMLElements.POPU String instName = popName + "[i]"; // main.append(instName + " = h.Section()\n"); double defaultRadius = 5; - main.append(bIndent+" h." + instName + ".L = " + defaultRadius * 2 + "\n"); - main.append(bIndent+" h." + instName + "(0.5).diam = " + defaultRadius * 2 + "\n"); + double length = defaultRadius * 2; + double diameter = defaultRadius * 2; if(popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_CELL_CAP_COMP_TYPE) || popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) { double capTotSI = -1; - + if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_CELL_CAP_COMP_TYPE)) { - if (popComp.hasParam("refract") && popComp.getParamValue("refract").getDoubleValue()==0) + //main.append(bIndent+" #...\n"); + if (popComp.hasParam("length")) + { + length = popComp.getParamValue("length").getDoubleValue() * 1e6; + } + if (popComp.hasParam("diameter")) + { + diameter = popComp.getParamValue("diameter").getDoubleValue() * 1e6; + } + + if (popComp.hasParam("refract") && popComp.getParamValue("refract").getDoubleValue()==0) { throw new NeuroMLException("Unfortunately the NEURON export for IaF cells cannot *YET* handle " + "cases when refract = 0 (as in cell "+popComp.getID()+")"); } capTotSI = popComp.getParamValue("C").getDoubleValue(); } - else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) + else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) { - if (popComp.hasParam("tau_refrac") && popComp.getParamValue("tau_refrac").getDoubleValue()==0) + if (popComp.hasParam("tau_refrac") && popComp.getParamValue("tau_refrac").getDoubleValue()==0) { throw new NeuroMLException("Unfortunately the NEURON export for PyNN cells cannot *YET* handle " + "cases when tau_refrac = 0 (as in cell "+popComp.getID()+")"); } capTotSI = popComp.getParamValue("cm").getDoubleValue() * 1e-9; } - - double area = 4 * Math.PI * defaultRadius * defaultRadius; + + double area = Math.PI * length * diameter; double specCapNeu = 10e13 * capTotSI / area; - main.append(bIndent+" h." + instName + "(0.5).cm = " + specCapNeu + "\n"); + main.append(bIndent+" h." + instName + "(0.5).cm = " + specCapNeu + " # Computed from area "+area+"\n"); } else { @@ -587,6 +639,9 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) main.append(bIndent+" h." + instName + "(0.5).cm = 318.31\n"); } + main.append(bIndent+" h." + instName + ".L = " + length + " # length to use for section in Neuron\n"); + main.append(bIndent+" h." + instName + "(0.5).diam = " + diameter + " # diameter to use for section in Neuron\n"); + main.append(bIndent+" h." + instName + ".push()\n"); main.append(bIndent+" h(\" " + instName.replaceAll("\\[i\\]", "[%i]") + " { " + mechName + "[%i] = new " + popComp.getID() + "(0.5) } \"%(i,i))\n\n"); @@ -604,7 +659,9 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) LemsCollection pvs = popComp.getParamValues(); for(ParamValue pv : pvs) { - main.append(bIndent+" h." + hocMechName + "." + pv.getName() + " = " + NRNUtils.convertToNeuronUnits((float) pv.getDoubleValue(), pv.getDimensionName()) + "\n"); + main.append(bIndent+" h." + hocMechName + "." + pv.getName() + + " = " + NRNUtils.convertToNeuronUnits((float) pv.getDoubleValue(), pv.getDimensionName()) + + " # NRN unit is: "+NRNUtils.getNeuronUnit(pv.getDimensionName())+"\n"); } if (!popComp.getComponentType().isOrExtends(NeuroMLElements.SPIKE_ARRAY) && @@ -615,28 +672,28 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) main.append(bIndent+" # Spiking element ("+popComp.getComponentType().getName()+"), will require seeding...\n"); main.append(bIndent+" rand = h.Random()\n"); main.append(bIndent+" self.randoms.append(rand)\n"); - + main.append(bIndent+" #print(\"Seeding random generator on "+hocMechName+" (i=%i) with stim seed %s\"%(i, self.seed))\n"); main.append(bIndent+" self._init_stim_randomizer(rand,\""+popName+"\",i, self.seed)\n"); main.append(bIndent+" rand.negexp(1)\n"); main.append(bIndent+" h."+hocMechName+".noiseFromRandom(rand)\n\n"); - - } - + + } + if(popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_RATE_UNIT)) { main.append(bIndent+" # use internal i_cap to gather info on incoming currents\n"); main.append(bIndent+" h(\"setpointer " + NRNUtils.getMechanismName(popComp, popName) + "[%i].isyn_in, "+popName+"[%i].i_cap(0.5)\"%(i,i))\n\n"); } - + main.append(bIndent+" h.pop_section()\n\n"); main.append(bIndent+" self.next_global_id+=1\n\n"); - - + + for (Integer cell_id: locationStrs.keySet()) { main.append(bIndent+"h(\" " + popName + "["+cell_id+"] { pt3dclear() } \")\n"); - main.append(bIndent+"h(\" " + popName + "["+cell_id+"] { pt3dadd"+locationStrs.get(cell_id).replace("XXX","(5)")+" } \")\n"); - main.append(bIndent+"h(\" " + popName + "["+cell_id+"] { pt3dadd"+locationStrs.get(cell_id).replace("XXX","(-5)")+" } \")\n"); + main.append(bIndent+"h(\" " + popName + "["+cell_id+"] { pt3dadd"+locationStrs.get(cell_id).replace("HALF_LENGTH","("+length/2.+")").replace("DIAMETER","("+diameter+")")+" } \")\n"); + main.append(bIndent+"h(\" " + popName + "["+cell_id+"] { pt3dadd"+locationStrs.get(cell_id).replace("HALF_LENGTH","("+length/-2.+")").replace("DIAMETER","("+diameter+")")+" } \")\n"); } main.append("\n"); @@ -646,14 +703,14 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) // / Add projections/connections E.info("Adding projections/connections..."); - + String synObjArrayName = null; ArrayList projections = targetComp.getChildrenAL("projections", generateAlphabetical); - + // TODO: change this to use arrays when vars are recorded too... boolean synArrayFormat = !NRNUtils.isPlottingSavingSynVariables(simCpt, nogui); - + HashMap segmentSynapseCounts = new HashMap(); for(Component projection : projections) @@ -680,7 +737,7 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) Component synapseComp = projection.getRefComponents().get("synapse"); generateModForComp(synapseComp); - + String netConnObjArrayName = null; if (synArrayFormat) @@ -729,12 +786,12 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) { postSecName = postPop + "[" + postCellId + "]"; } - + String segSynRef = String.format("syn_%s_%s_%s_%s", postPop,postCellId, postSegmentId, synapse); if (!segmentSynapseCounts.containsKey(segSynRef)) segmentSynapseCounts.put(segSynRef, 0); int synIndex = segmentSynapseCounts.get(segSynRef); - + String synObjName = null; if (synArrayFormat) { @@ -745,7 +802,7 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) synObjName = String.format("%s_%s", segSynRef, connIndex); } segmentSynapseCounts.put(segSynRef, synIndex+1); - + float postFract = postFractionAlong0; if(postCell != null) { @@ -753,12 +810,12 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) } float preFract = preFractionAlong0; - + if(preCell != null) { preFract = !CellUtils.hasUnbranchedNonOverlappingInfo(preCell) ? preFractionAlong0 : (float) CellUtils.getFractionAlongSegGroupLength(preCell, preSecName.split("\\.")[1], preSegmentId, preFractionAlong0); } - + String sourceVarToListenFor = "&v("+ preFract+")"; float weight = 1; @@ -768,11 +825,11 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) weight = Float.parseFloat(conn.getAttributeValue("weight")); delay = NRNUtils.convertToNeuronUnits(conn.getAttributeValue("delay"), lems); } - + String comment = String.format(Locale.US, "Connection %s: cell %d, seg %d (%s) [%s on %s] -> cell %d, seg %d (%s) [%s on %s], weight: %s, delay %s", conn.getID(), preCellId, preSegmentId, preFractionAlong0, preFract, preSecName, postCellId, postSegmentId, postFractionAlong0, postFract, postSecName, weight, delay); //System.out.println("comment@: "+comment); addComment(main, comment," "); - + if (!synArrayFormat) { main.append(String.format(bIndent+"h(\"objectvar %s\")\n", synObjName)); @@ -782,7 +839,7 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) if(preCell != null) { float threshold; - + if (getMembraneProperties(preCell).getSpikeThresh().size()>0) { SpikeThresh st = getMembraneProperties(preCell).getSpikeThresh().get(0); @@ -816,18 +873,18 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) String hocMechName = NRNUtils.getMechanismName(preComp, prePop) + "["+preCellId+"]"; sourceVarToListenFor = hocMechName; } - + if (synArrayFormat) { main.append(String.format(Locale.US, bIndent+"h(\"%s %s[%d] = new NetCon(%s, %s, %s, %s, %s)\") \n\n", preSecName, netConnObjArrayName, connIndex, sourceVarToListenFor, synObjName, threshold, delay, weight)); } else - { + { String netConnName = String.format("nc_%s_%d", synObjName, connIndex); main.append(String.format(bIndent+"h(\"objectvar %s\")\n", netConnName)); main.append(String.format(Locale.US, bIndent+"h(\"%s %s = new NetCon(%s, %s, %s, %s, %s)\") \n\n", preSecName, netConnName, sourceVarToListenFor, synObjName, threshold, delay, weight)); } - + } connIndex++; } @@ -905,7 +962,7 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) String info1 = String.format("Adding connection from %s to %s", fromRef, postRef); addComment(main, info1,bIndent); - + String segSynRef = String.format("syn_%s_%s_%s_%s", postPop, postCellId, 0, synapseComp.getID()); if (!segmentSynapseCounts.containsKey(segSynRef)) segmentSynapseCounts.put(segSynRef, 0); @@ -932,7 +989,7 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) String hocMechName = NRNUtils.getMechanismName(fromComp, prePop) + "["+preCellId+"]"; sourceVarToListenFor = hocMechName; } - + main.append(String.format(bIndent+"h(\"%s a_%s[%d].synlist.append(new NetCon(%s, %s, %g, %g, %g))\") # ...\n\n", preSecName, postPop, postCellId, sourceVarToListenFor, synObjName, threshold, delay, weight)); } else @@ -977,7 +1034,7 @@ else if (popComp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) addComment(main, "###################### Electrical Projection: "+id," "); info = String.format("Adding electrical projection: %s from %s to %s, with %d connection(s)", id, prePop, postPop, number); main.append(bIndent+"print(\""+info+"\")\n\n"); - + ArrayList connChildren = ep.getChildrenAL("connections"); connChildren.addAll(ep.getChildrenAL("connectionInstances")); @@ -1017,7 +1074,7 @@ else if (ec.getComponentType().isOrExtends(NeuroMLElements.ELECTRICAL_CONNECTION float preFractionAlong0 = ec.hasAttribute("preFractionAlong") ? Float.parseFloat(ec.getAttributeValue("preFractionAlong")) : 0.5f; float postFractionAlong0 = ec.hasAttribute("postFractionAlong") ? Float.parseFloat(ec.getAttributeValue("postFractionAlong")) : 0.5f; - + // System.out.println("preCellId: "+preCellId+", preSegmentId: "+preSegmentId+", preFractionAlong: "+preFractionAlong); String preSecName; @@ -1042,7 +1099,7 @@ else if (ec.getComponentType().isOrExtends(NeuroMLElements.ELECTRICAL_CONNECTION { postSecName = postPop + "[" + postCellId + "]"; } - + float postFract = postFractionAlong0; if(postCell != null) { @@ -1054,20 +1111,20 @@ else if (ec.getComponentType().isOrExtends(NeuroMLElements.ELECTRICAL_CONNECTION { preFract = !CellUtils.hasUnbranchedNonOverlappingInfo(preCell) ? preFractionAlong0 : (float) CellUtils.getFractionAlongSegGroupLength(preCell, preSecName.split("\\.")[1], preSegment, preFractionAlong0); } - + float weight = 1; if (ec.getComponentType().isOrExtends(NeuroMLElements.ELECTRICAL_CONNECTION_INSTANCE_WEIGHT)) { weight = Float.parseFloat(ec.getAttributeValue("weight")); } - + String comment = String.format(Locale.US, "Elect Connection %s: cell %d, seg %d (%s) [%s on %s] -> cell %d, seg %d (%s) [%s on %s], weight: %s", ec.getID(), preCellId, preSegment, preFractionAlong0, preFract, preSecName, postCellId, postSegment, postFractionAlong0, postFract, postSecName, weight); - + addComment(main, comment," "); main.append(String.format(Locale.US, bIndent+"h(\"%s { %s[%d] = new %s(%s) }\")\n", preSecName, synObjNameA, index, synapseComp.getID(), preFract)); main.append(String.format(Locale.US, bIndent+"h(\"%s { %s[%d] = new %s(%s) }\")\n", postSecName, synObjNameB, index, synapseComp.getID(), postFract)); - + if (weight!=1) { main.append(String.format(Locale.US, bIndent+"h(\"%s { %s[%d].weight = %s }\")\n", preSecName, synObjNameA, index, weight)); @@ -1109,7 +1166,7 @@ else if (ec.getComponentType().isOrExtends(NeuroMLElements.ELECTRICAL_CONNECTION addComment(main, "###################### Continuous Projection: "+id," "); info = String.format("Adding continuous projection: %s from %s to %s, with %d connection(s)", id, prePop, postPop, number); main.append(bIndent+"print(\""+info+"\")\n\n"); - + ArrayList connChildren = ep.getChildrenAL("connections"); connChildren.addAll(ep.getChildrenAL("connectionInstances")); @@ -1133,7 +1190,7 @@ else if (ec.getComponentType().isOrExtends(NeuroMLElements.ELECTRICAL_CONNECTION { int preCellId = -1; int postCellId = -1; - + if(cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION)) { preCellId = Integer.parseInt(cc.getStringValue("preCell")); @@ -1173,7 +1230,7 @@ else if(cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION_ { postSecName = postPop + "[" + postCellId + "]"; } - + float postFract = postFractionAlong0; if(postCell != null) { @@ -1185,15 +1242,15 @@ else if(cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION_ { preFract = !CellUtils.hasUnbranchedNonOverlappingInfo(preCell) ? preFractionAlong0 : (float) CellUtils.getFractionAlongSegGroupLength(preCell, preSecName.split("\\.")[1], preSegment, preFractionAlong0); } - + float weight = 1; if (cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION_INSTANCE_WEIGHT)) { weight = Float.parseFloat(cc.getAttributeValue("weight")); } - + String comment = String.format(Locale.US, "Continuous Connection %s: cell %d, seg %d (%s) [%s on %s] -> cell %d, seg %d (%s) [%s on %s], weight: %s", cc.getID(), preCellId, preSegment, preFractionAlong0, preFract, preSecName, postCellId, postSegment, postFractionAlong0, postFract, postSecName, weight); - + addComment(main, comment," "); main.append(String.format(Locale.US, bIndent+"h(\"%s { %s[%d] = new %s(%f) }\")\n", preSecName, preCompObjName, contConnIndex, preComponent.getID(), preFract)); @@ -1210,7 +1267,7 @@ else if(cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION_ String postPrefix = ""; String preArg = "("+preFract+")"; String postArg = "("+postFract+")"; - + if(postComponent.getComponentType().getName().toLowerCase().contains("rate")) { peerVar = "r"; @@ -1264,9 +1321,9 @@ else if(cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION_ String scale = lineComp.getStringValue("scale"); LEMSQuantityPathNeuron lqp = new LEMSQuantityPathNeuron(quantity, scale, targetComp, compMechNamesHoc, popsOrComponents, compIdsVsCells, hocRefsVsInputs, lems); - + //System.out.println("lqp: "+lqp); - + if(plots.get(dispGraph) == null) { plots.put(dispGraph, new ArrayList()); @@ -1292,8 +1349,14 @@ else if(cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION_ main.append(toRec); main.append(bIndent+"h.tstop = tstop\n\n"); - main.append(bIndent+"h.dt = dt\n\n"); - main.append(bIndent+"h.steps_per_ms = 1/h.dt\n\n"); + main.append(bIndent+"if self.abs_tol is not None and self.rel_tol is not None:\n"); + main.append(bIndent+" cvode = h.CVode()\n"); + main.append(bIndent+" cvode.active(1)\n"); + main.append(bIndent+" cvode.atol(self.abs_tol)\n"); + main.append(bIndent+" cvode.rtol(self.rel_tol)\n"); + main.append(bIndent+"else:\n"); + main.append(bIndent+" h.dt = dt\n"); + main.append(bIndent+" h.steps_per_ms = 1/h.dt\n\n"); if(!nogui) { @@ -1336,14 +1399,15 @@ else if(cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION_ columnsPre.get(timeRef).add(bIndent+"h(' objectvar v_" + timeRef + " ')"); columnsPre.get(timeRef).add(bIndent+"h(' { v_" + timeRef + " = new Vector() } ')"); columnsPre.get(timeRef).add(bIndent+"h(' { v_" + timeRef + ".record(&t) } ')"); - columnsPre.get(timeRef).add(bIndent+"h.v_" + timeRef + ".resize((h.tstop * h.steps_per_ms) + 1)"); + columnsPre.get(timeRef).add(bIndent+"if self.abs_tol is None or self.rel_tol is None:\n"); + columnsPre.get(timeRef).add(bIndent+" h.v_" + timeRef + ".resize((h.tstop * h.steps_per_ms) + 1)"); columnsPost0.get(timeRef).add(bIndent+"py_v_" + timeRef + " = [ t/1000 for t in h.v_" + timeRef + ".to_python() ] # Convert to Python list for speed..."); columnsPostTraces.get(timeRef).add(bIndent+" f_" + timeRef + "_f2.write('%f'% py_v_" + timeRef + "[i]) # Save in SI units..."); - HashMap> writingVariables = new HashMap>(); + HashMap> writingVariables = new HashMap>(); for(Component ofComp : simCpt.getAllChildren()) { @@ -1358,7 +1422,7 @@ else if(cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION_ if(columnsPostTraces.get(outfileId) == null) { columnsPostTraces.put(outfileId, new ArrayList()); - + } if(columnsPost0.get(outfileId) == null) { @@ -1389,16 +1453,21 @@ else if(cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION_ String scale = "1"; LEMSQuantityPathNeuron lqp = new LEMSQuantityPathNeuron(quantity, scale, targetComp, compMechNamesHoc, popsOrComponents, compIdsVsCells, hocRefsVsInputs, lems); - + //System.out.println("lqp: "+lqp); columnsPre.get(outfileId).add(bIndent+"# Column: " + lqp.getQuantity()); columnsPre.get(outfileId).add(bIndent+"h(' objectvar v_" + colId + " ')"); columnsPre.get(outfileId).add(bIndent+"h(' { v_" + colId + " = new Vector() } ')"); columnsPre.get(outfileId).add(bIndent+"h(' { v_" + colId + ".record(&" + lqp.getNeuronVariableReference() + ") } ')"); - columnsPre.get(outfileId).add(bIndent+"h.v_" + colId + ".resize((h.tstop * h.steps_per_ms) + 1)"); + columnsPre.get(outfileId).add(bIndent+"if self.abs_tol is None or self.rel_tol is None:\n"); + columnsPre.get(outfileId).add(bIndent+" h.v_" + colId + ".resize((h.tstop * h.steps_per_ms) + 1)"); float conv = NRNUtils.getNeuronUnitFactor(lqp.getDimension().getName()); + if (lqp.getDimension().getName().equals("conductanceDensity")) + { + conv = conv = NRNUtils.getNeuronUnitFactor("conductanceDensity_hoc"); + } String factor = (conv == 1) ? "" : " / " + conv; columnsPost0.get(outfileId).add(bIndent+ @@ -1438,7 +1507,7 @@ else if(cc.getComponentType().isOrExtends(NeuroMLElements.CONTINUOUS_CONNECTION_ columnsPre.get(outfileId).add(bIndent+"h(' objectvar " + spikeVecName + ", t_" + spikeVecName + " ')"); columnsPre.get(outfileId).add(bIndent+"h(' { " + spikeVecName + " = new Vector() } ')"); columnsPre.get(outfileId).add(bIndent+"h(' { t_" + spikeVecName + " = new Vector() } ')"); - + columnsPre.get(outfileId).add(bIndent+"h(' objref "+ncName+", nil ')"); columnsPostSpikes.get(outfileId).add(bIndent+"h(' objref "+ncName+" ')"); @@ -1476,15 +1545,15 @@ else if (eofFormat.equals(EventWriter.FORMAT_ID_TIME)) String srcSecName; float threshold = 0; Component comp = this.popIdsVsComps.get(srcCellPop); - + if (comp.getComponentType().isOrExtends(NeuroMLElements.BASE_SPIKE_SOURCE_COMP_TYPE) || comp.getComponentType().isOrExtends(NeuroMLElements.BASE_VOLT_DEP_CURR_SRC_SPIKING_COMP_TYPE)) { - + String mechName = NRNUtils.getMechanismName(comp, srcCellPop); - - columnsPre.get(outfileId).add(bIndent+"# It's a spike source, will listen to "+mechName+"..." ); - + + columnsPre.get(outfileId).add(bIndent+"# It's a spike source, will listen to "+mechName+"..." ); + columnsPre.get(outfileId).add(bIndent+"h(' "+ncName+" = new NetCon("+mechName+"["+srcCellNum+"], nil) ')"); columnsPre.get(outfileId).add(bIndent+"h(' { "+ncName+".record(t_"+spikeVecName+", "+spikeVecName+", "+id+") } ')"); @@ -1496,13 +1565,13 @@ else if (eofFormat.equals(EventWriter.FORMAT_ID_TIME)) NamingHelper nh0 = new NamingHelper(srcCell); srcSecName = String.format("a_%s[%s].%s", srcCellPop, srcCellNum, nh0.getNrnSectionName(srcCell.getMorphology().getSegment().get(0))); - if (srcCell.getBiophysicalProperties().getMembraneProperties().getSpikeThresh().isEmpty()) + if (getMembraneProperties(srcCell).getSpikeThresh().isEmpty()) { threshold = 0; } else { - SpikeThresh st = srcCell.getBiophysicalProperties().getMembraneProperties().getSpikeThresh().get(0); + SpikeThresh st = getMembraneProperties(srcCell).getSpikeThresh().get(0); if (!st.getSegmentGroup().equals(NeuroMLElements.SEGMENT_GROUP_ALL)) { throw new NeuroMLException("Cannot yet handle when it is not on segmentGroup all"); @@ -1541,7 +1610,7 @@ else if (eofFormat.equals(EventWriter.FORMAT_ID_TIME)) main.append(bIndent+"self.initialized = False\n\n"); main.append(bIndent+"self.sim_end = -1 # will be overwritten\n\n"); - + main.append(bIndent+"setup_end = time.time()\n"); main.append(bIndent+"self.setup_time = setup_end - self.setup_start\n"); //setup_time = save_end - self.sim_end @@ -1552,12 +1621,17 @@ else if (eofFormat.equals(EventWriter.FORMAT_ID_TIME)) { main.append(bIndent+"h.nrncontrolmenu()\n\n\n"); } - + main.append(" def run(self):\n\n"); main.append(bIndent+"self.initialized = True\n"); main.append(bIndent+"sim_start = time.time()\n"); - main.append(bIndent+"print(\"Running a simulation of %sms (dt = %sms; seed=%s)\" % (h.tstop, h.dt, self.seed))\n\n"); + + main.append(bIndent+"if self.abs_tol is not None and self.rel_tol is not None:\n"); + main.append(bIndent+" print(\"Running a simulation of %sms (cvode abs_tol = %sms, rel_tol = %sms; seed=%s)\" % (h.tstop, self.abs_tol, self.rel_tol, self.seed))\n"); + main.append(bIndent+"else:\n"); + main.append(bIndent+" print(\"Running a simulation of %sms (dt = %sms; seed=%s)\" % (h.tstop, h.dt, self.seed))\n\n"); + main.append(bIndent+"try:\n"); main.append(bIndent+" h.run()\n"); main.append(bIndent+"except Exception as e:\n"); @@ -1570,11 +1644,11 @@ else if (eofFormat.equals(EventWriter.FORMAT_ID_TIME)) { main.append(bIndent+" return\n\n\n"); } - + main.append(bIndent+"self.sim_end = time.time()\n"); main.append(bIndent+"self.sim_time = self.sim_end - sim_start\n"); main.append(bIndent+"print(\"Finished NEURON simulation in %f seconds (%f mins)...\"%(self.sim_time, self.sim_time/60.0))\n\n"); - + main.append(bIndent+"try:\n"); main.append(bIndent+" self.save_results()\n"); main.append(bIndent+"except Exception as e:\n"); @@ -1587,20 +1661,20 @@ else if (eofFormat.equals(EventWriter.FORMAT_ID_TIME)) { main.append(bIndent+" return\n\n\n"); } - + main.append(" def advance(self):\n\n"); main.append(bIndent+"if not self.initialized:\n"); main.append(bIndent+" h.finitialize()\n"); main.append(bIndent+" self.initialized = True\n\n"); main.append(bIndent+"h.fadvance()\n\n\n"); - + main.append(" ###############################################################################\n"); main.append(" # Hash function to use in generation of random value\n"); main.append(" # This is copied from NetPyNE: https://github.com/Neurosim-lab/netpyne/blob/master/netpyne/simFuncs.py\n"); main.append(" ###############################################################################\n"); main.append(" def _id32 (self,obj): \n"); main.append(bIndent+"return int(hashlib.md5(obj.encode('utf-8')).hexdigest()[0:8],16) # convert 8 first chars of md5 hash in base 16 to int\n\n\n"); - + main.append(" ###############################################################################\n"); main.append(" # Initialize the stim randomizer\n"); main.append(" # This is copied from NetPyNE: https://github.com/Neurosim-lab/netpyne/blob/master/netpyne/simFuncs.py\n"); @@ -1608,7 +1682,7 @@ else if (eofFormat.equals(EventWriter.FORMAT_ID_TIME)) main.append(" def _init_stim_randomizer(self,rand, stimType, gid, seed): \n"); main.append(bIndent+"#print(\"INIT STIM %s; %s; %s; %s\"%(rand, stimType, gid, seed))\n"); main.append(bIndent+"rand.Random123(self._id32(stimType), gid, seed)\n\n\n"); - + main.append(" def save_results(self):\n\n"); main.append(bIndent+"print(\"Saving results at t=%s...\"%h.t)\n\n"); main.append(bIndent+"if self.sim_end < 0: self.sim_end = time.time()\n\n"); @@ -1628,7 +1702,7 @@ else if (eofFormat.equals(EventWriter.FORMAT_ID_TIME)) for(String f : refList) { - addComment(main, "###################### File to save: " + outfiles.get(f)+" ("+f+")",bIndent); + addComment(main, "###################### File to save: " + outfiles.get(f)+" ("+f+"). Note, saving in SI units",bIndent); for(String col : columnsPost0.get(f)) { main.append(col + "\n"); @@ -1675,7 +1749,7 @@ else if (eofFormat.equals(EventWriter.FORMAT_ID_TIME)) main.append(bIndent+"save_end = time.time()\n"); main.append(bIndent+"save_time = save_end - self.sim_end\n"); main.append(bIndent+"print(\"Finished saving results in %f seconds\"%(save_time))\n\n"); - + if (target.reportFile!=null) { main.append(bIndent+"self.report_file.write('StartTime=%s\\n'%datetime.datetime.fromtimestamp(self.setup_start).strftime('%Y-%m-%d %H:%M:%S'))\n"); @@ -1685,18 +1759,18 @@ else if (eofFormat.equals(EventWriter.FORMAT_ID_TIME)) main.append(bIndent+"self.report_file.close()\n\n"); main.append(bIndent+"print(\"Saving report of simulation to %s\"%('"+target.reportFile+"'))\n\n"); } - + main.append(bIndent+"print(\"Done\")\n\n"); if(nogui) { main.append(bIndent+"quit()\n\n\n"); } - - + + main.append("if __name__ == '__main__':\n\n"); - main.append(" ns = NeuronSimulation(tstop="+len+", dt="+dt+", seed="+seed+")\n\n"); - + main.append(" ns = NeuronSimulation(tstop="+len+", dt="+dt+", seed="+seed+", abs_tol="+abs_tol+", rel_tol="+rel_tol+")\n\n"); + main.append(" ns.run()\n\n"); return main.toString(); @@ -1736,7 +1810,7 @@ private void processInputLists(StringBuilder main, Component targetComp) throws ContentError, NeuroMLException { ArrayList ils = targetComp.getChildrenAL("inputs", generateAlphabetical); - + if (ils.size()>0) { main.append(bIndent+"print(\"Processing "+ils.size()+" input lists\")\n\n"); @@ -1822,7 +1896,7 @@ private String generateSecName(String popName, int cellNum, int segmentId) { segment = cell.getMorphology().getSegment().get(0); } - + NamingHelper nh0 = new NamingHelper(cell); secName = String.format("a_%s[%s].%s", popName, cellNum, nh0.getNrnSectionName(segment)); } else { @@ -1832,7 +1906,7 @@ private String generateSecName(String popName, int cellNum, int segmentId) } private float parseFractionAlong(Component input) throws ContentError, NeuroMLException { - + String targetString = input.getStringValue("target"); String popName = Utils.parseCellRefStringForPopulation(targetString); String cellId = popIdsVsCellIds.get(popName); @@ -1840,7 +1914,7 @@ private float parseFractionAlong(Component input) throws ContentError, NeuroMLEx Cell cell = compIdsVsCells.get(cellId); if (cell==null) return fractSeg; - + if (cell.getMorphology().getSegment().size()==1) return fractSeg; NamingHelper nh0 = new NamingHelper(cell); @@ -1855,34 +1929,34 @@ private float parseFractionAlong(Component input) throws ContentError, NeuroMLEx segment = cell.getMorphology().getSegment().get(0); } String secName = nh0.getNrnSectionName(segment); - - + + float fract = !CellUtils.hasUnbranchedNonOverlappingInfo(cell) ? fractSeg : (float) CellUtils.getFractionAlongSegGroupLength(cell, secName, segmentId, fractSeg); - + return fract; } private int parseSegmentId(Component input) throws ContentError { return input.hasAttribute("segmentId") ? Integer.parseInt(input.getAttributeValue("segmentId")) : 0; } - + boolean timeDepLiteralHelperMethodAdded = false; ArrayList createdTimedInputs = new ArrayList(); private void processTimeDependentLiterals(StringBuilder main, Component input, Component inputComp, String inputList) throws ContentError, NeuroMLException, ParseError, LEMSException { - + // TODO Auto-generated method stub String inputListName = NRNUtils.getSafeName(inputList); float weight = input.hasStringValue("weight") ? Float.parseFloat(input.getStringValue("weight")) : 1; - + Component synapse = inputComp.getRefComponents().get("synapse"); String synSafeName = NRNUtils.getSafeName(synapse.getID()); String synFullName = "self."+inputListName + "_" + synSafeName+"_"+input.getID(); - + addComment(main, "Generating event source for input " + input +", comp "+inputComp+", weight: "+weight, bIndent); addComment(main, "Name: " + synFullName, bIndent); - + main.append(String.format(bIndent+"%s = h.%s(%s, sec=h.%s) # Synapse of type %s on %s\n", synFullName, synSafeName, @@ -1890,7 +1964,7 @@ private void processTimeDependentLiterals(StringBuilder main, Component input, C parseInputSecName(input), synapse.getID(), parseInputSecName(input))); - + if (!timeDepLiteralHelperMethodAdded) { String helperFunc = bIndent+"# Helper method for creating NetStim to emit at time tstim\n"+bIndent+"def singleNetStimT(tstim):\n"+bIndent+"\tn=h.NetStim()\n"+bIndent+"\tn.number = 1\n"+bIndent+"\tn.start=tstim\n"+bIndent+"\treturn n\n"; @@ -1905,7 +1979,7 @@ private void processTimeDependentLiterals(StringBuilder main, Component input, C } String synInputName = String.format("syn_input_netstims_%s", inputComp.getID()); String stimName = String.format("self.%s", synInputName); - + //stimName = String.format("%s_stims", inputName); if (!createdTimedInputs.contains(synInputName)) { @@ -1934,7 +2008,7 @@ private void generateModForComp(Component comp) throws LEMSException, ContentErr } return; } - + String mod = generateModFile(comp); saveModToFile(comp, mod); } @@ -1950,7 +2024,7 @@ private void writeModFile(Component comp, ChannelConductanceOption option) throw } } - + public File saveModToFile(Component comp, String mod) throws ContentError { File modFile = new File(getOutputFolder(), NRNUtils.getSafeName(comp.getID()) + ".mod"); @@ -1973,8 +2047,8 @@ public File saveModToFile(Component comp, String mod) throws ContentError } return modFile; } - - public MembraneProperties getMembraneProperties(Cell cell) + + public MembraneProperties getMembraneProperties(Cell cell) { if (cell instanceof Cell2CaPools) { Cell2CaPools cell2ca = (Cell2CaPools)cell; @@ -1987,11 +2061,11 @@ public MembraneProperties getMembraneProperties(Cell cell) return bp.getMembraneProperties(); } } - - private Cell getCellFromComponent(Component cellComponent) throws LEMSException, NeuroMLException + + private Cell getCellFromComponent(Component cellComponent) throws LEMSException, NeuroMLException { Cell cell; - if (compIdsVsCells.containsKey(cellComponent.getID())) + if (compIdsVsCells.containsKey(cellComponent.getID())) { cell = compIdsVsCells.get(cellComponent.getID()); } @@ -2002,12 +2076,12 @@ private Cell getCellFromComponent(Component cellComponent) throws LEMSException, } return cell; } - - public IntracellularProperties convertCellWithMorphology(Component cellComponent) throws LEMSException, NeuroMLException + + public IntracellularProperties convertCellWithMorphology(Component cellComponent) throws LEMSException, NeuroMLException { - + Cell cell = getCellFromComponent(cellComponent); - + String cellString = generateCellFile(cell); String cellName = cellComponent.getID(); @@ -2046,8 +2120,8 @@ public IntracellularProperties convertCellWithMorphology(Component cellComponent for(Component channelDensity : mpComp.getChildrenAL("channelDensities")) { - if (channelDensity.getTypeName().equals("channelDensity") || - channelDensity.getTypeName().equals("channelDensityNonUniform")|| + if (channelDensity.getTypeName().equals("channelDensity") || + channelDensity.getTypeName().equals("channelDensityNonUniform")|| channelDensity.getTypeName().equals("channelDensityVShift")) { ChannelConductanceOption option = ChannelConductanceOption.FIXED_REVERSAL_POTENTIAL; option.erev = NRNUtils.convertToNeuronUnits((float)channelDensity.getParamValue("erev").getDoubleValue(), "voltage"); @@ -2082,7 +2156,7 @@ else if (channelDensity.getTypeName().equals("channelDensityGHK2") ){ { throw new ContentError("Error writing to file: " + cellFile.getAbsolutePath(), ex); } - + return ip; } @@ -2298,7 +2372,8 @@ else if(condOption.equals(ChannelConductanceOption.USE_GHK2)) } } - blockNeuron.append("\nRANGE gion "); + blockNeuron.append("\nRANGE gion"); + blockNeuron.append("\nRANGE i__" + mechName + " : a copy of the variable for current which makes it easier to access from outside the mod file"); if(condOption == null || condOption.equals(ChannelConductanceOption.FIXED_REVERSAL_POTENTIAL) || condOption.equals(ChannelConductanceOption.USE_NERNST)) { @@ -2347,8 +2422,9 @@ else if(comp.getComponentType().isOrExtends(NeuroMLElements.CONC_MODEL_COMP_TYPE blockAssigned.append(""+ion+"i (mM)\n"); blockAssigned.append(""+ion+"o (mM)\n"); blockAssigned.append("i"+ion+" (mA/cm2)\n"); - blockAssigned.append("diam (um)\n"); - blockAssigned.append("area (um2)\n"); + blockAssigned.append("i__"+mechName+" (mA/cm2)\n"); + blockAssigned.append("diam (um) : Added to facilitate access to section's diam\n"); + blockAssigned.append("area (um2) : Added to facilitate access to section's area\n"); blockParameter.append(NeuroMLElements.CONC_MODEL_SURF_AREA + " "+NRNUtils.getNeuronUnit("area")+"\n"); @@ -2357,12 +2433,12 @@ else if(comp.getComponentType().isOrExtends(NeuroMLElements.CONC_MODEL_COMP_TYPE blockParameter.append(totalCaCurrent + " "+NRNUtils.getNeuronUnit("current")+"\n"); - ratesMethod.append(NeuroMLElements.CONC_MODEL_SURF_AREA + " = area : " + ratesMethod.append(NeuroMLElements.CONC_MODEL_SURF_AREA + " = (1e-08)*(area) : " +NeuroMLElements.CONC_MODEL_SURF_AREA+" has units "+NRNUtils.getNeuronUnit("area") +", area (built in to NEURON) is in um^2...\n\n"); - ratesMethod.append(totalCaCurrent + " = -1 * (0.01) * i"+ion+" * " + NeuroMLElements.CONC_MODEL_SURF_AREA - + " : "+totalCaCurrent+" has units "+NRNUtils.getNeuronUnit("current")+" ; i"+ion+" (built in to NEURON) has units (mA/cm2)...\n\n"); + ratesMethod.append(totalCaCurrent + " = (1e6) * (-1 * i"+ion+" * " + NeuroMLElements.CONC_MODEL_SURF_AREA + + ") : "+totalCaCurrent+" has units "+NRNUtils.getNeuronUnit("current")+" ; i"+ion+" (built in to NEURON) has units (mA/cm2)...\n\n"); blockNeuron.append("GLOBAL " + NeuroMLElements.CONC_MODEL_INIT_CONC + "\n"); blockNeuron.append("GLOBAL " + NeuroMLElements.CONC_MODEL_INIT_EXT_CONC + "\n"); @@ -2395,7 +2471,7 @@ else if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_SPIKE_SOURCE_CO { blockAssigned.append("v (mV)\n"); } - + if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_SYNAPSE_COMP_TYPE)) { blockAssigned.append("? Standard Assigned variables with baseSynapse\n"); @@ -2408,7 +2484,7 @@ else if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_SPIKE_SOURCE_CO { blockNetReceiveParams = "flag"; } - + if(comp.getComponentType().isOrExtends("baseRateUnit")) { blockNeuron.append("? Add pointer for incoming current\n"); @@ -2416,7 +2492,7 @@ else if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_SPIKE_SOURCE_CO blockNeuron.append("POINTER isyn_in\n\n"); blockAssigned.append("? Pointer for incoming current\n"); blockAssigned.append("isyn_in (nA)\n\n"); - + } String prefix = ""; @@ -2441,11 +2517,13 @@ else if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_SPIKE_SOURCE_CO { blockAssigned.append("e (mV)\n"); blockAssigned.append("i (mA/cm2)\n"); + blockAssigned.append("i__"+mechName+" (mA/cm2)\n"); } else { blockAssigned.append("e" + species + " (mV)\n"); blockAssigned.append("i" + species + " (mA/cm2)\n"); + blockAssigned.append("i__"+mechName+" (mA/cm2)\n"); } blockAssigned.append("\n"); if(hasCaDependency) @@ -2458,11 +2536,11 @@ else if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_SPIKE_SOURCE_CO } if(hasVShift) { - + if(!comp.getComponentType().isOrExtends(NeuroMLElements.ION_CHANNEL_V_SHIFT_TYPE)) { blockParameter.append("\n"+NRNUtils.vShift + " = 0 "+NRNUtils.getNeuronUnit("voltage")+" ? Will be used in rate expressions\n\n"); - + blockNeuron.append("RANGE "+NRNUtils.vShift + " : Can be set externally\n"); } } @@ -2491,6 +2569,7 @@ else if(condOption.equals(ChannelConductanceOption.USE_GHK2)) if(species == null || species.equals("non_specific")) { blockBreakpoint.append("i = gion * (v - e)\n"); + blockBreakpoint.append("i__" + mechName + " = -1 * i : set this variable to the current also - note -1 as channel current convention for LEMS used!\n"); } else { @@ -2506,6 +2585,7 @@ else if(condOption.equals(ChannelConductanceOption.USE_GHK2)) { blockBreakpoint.append("i" + species + " = gion * ghk2(v, cai, cao)\n"); } + blockBreakpoint.append("i__" + mechName + " = -1 * i" + species + " : set this variable to the current also - note -1 as channel current convention for LEMS used!\n"); } } // else if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_SYNAPSE_COMP_TYPE)) @@ -2661,7 +2741,7 @@ else if(condOption.equals(ChannelConductanceOption.USE_GHK2)) if(sv.getName().equals(NRNUtils.NEURON_VOLTAGE)) { - blockBreakpoint.append("\n" + NRNUtils.V_COPY_PREFIX + NRNUtils.NEURON_VOLTAGE + " = " + NRNUtils.NEURON_VOLTAGE); + ////////////blockBreakpoint.append("\n" + NRNUtils.V_COPY_PREFIX + NRNUtils.NEURON_VOLTAGE + " = " + NRNUtils.NEURON_VOLTAGE); if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_CELL_CAP_COMP_TYPE)) { @@ -2678,7 +2758,7 @@ else if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_PYNN_CELL)) } } } - + if (blockInitial.indexOf("random")>0 || blockNetReceive.indexOf("random")>0 || ratesMethod.indexOf("random")>0|| @@ -2919,7 +2999,7 @@ private void parseOnCondition(Component comp, String prefix, StringBuilder block if(!resetVoltage) // A "normal" OnCondition { boolean hasEvent = oc.getEventOuts().size()>=1; - + if (! (comp.getComponentType().isOrExtends(NeuroMLElements.BASE_SPIKE_SOURCE_COMP_TYPE) || comp.getComponentType().isOrExtends(NeuroMLElements.BASE_VOLT_DEP_CURR_SRC_SPIKING_COMP_TYPE))) { @@ -2985,7 +3065,7 @@ private void parseOnCondition(Component comp, String prefix, StringBuilder block } } } - + // Particularly important for for(Component childComp2 : childComp.getAllChildren()) { @@ -3014,12 +3094,12 @@ private void parseOnCondition(Component comp, String prefix, StringBuilder block } if(debug) { - //int y = 9; + //int y = 9; //if (comp.getTypeName().indexOf("Syn")<0 && !comp.getTypeName().equals("spikeGenerator")) //blockNetReceive.append(" printf(\"End Condition (" + NRNUtils.checkForStateVarsAndNested(cond, comp, paramMappings) + "), " + conditionFlag // + ", satisfied in " + comp.getTypeName() + " at time: %g, v: %g, isi: %g, tnext: %g\\n\", t, v, isi, tnext)\n"); } - + blockNetReceive.append("\n net_event(t)\n"); blockNetReceive.append(" WATCH (" + NRNUtils.checkForStateVarsAndNested(cond, comp, paramMappings) + ") " + conditionFlag + "\n"); blockNetReceive.append("\n}\n"); @@ -3042,11 +3122,11 @@ private void parseOnCondition(Component comp, String prefix, StringBuilder block for(StateAssignment sa : oc.getStateAssignments()) { blockNetReceive.append("\n " + prefix + sa.getStateVariable().getName() + " = " + NRNUtils.checkForStateVarsAndNested(sa.getValueExpression(), comp, paramMappings) + "\n"); - + if(sa.getStateVariable().getName().equals(NRNUtils.NEURON_VOLTAGE)) { blockNetReceive.append("\n " + prefix + NRNUtils.getStateVarName(sa.getStateVariable().getName()) + " = 0 : Setting rate of change of v to 0\n"); - + } } blockNetReceive.append("}\n"); @@ -3055,14 +3135,14 @@ private void parseOnCondition(Component comp, String prefix, StringBuilder block conditionFlag++; } } - + for(Component childComp : comp.getAllChildren()) { String prefixNew = getPrefix(childComp, prefix); if(!comp.getComponentType().isOrExtends(NeuroMLElements.SPIKE_ARRAY)) { // since this will be hard coded as a more efficient impl, see parseOnStart //parseParameters(childComp, prefixNew, prefix, rangeVars, stateVars, blockNeuron, blockParameter, paramMappings); - + //blockNetReceive.append("\n : Parsing child: "+childComp+" of "+comp+"\n"); parseOnCondition(childComp, prefixNew, blockBreakpoint, blockNetReceive, paramMappings, conditionFlag); } @@ -3120,8 +3200,8 @@ private void parseParameters(Component comp, String prefix, String prefixParent, paramMappingsComp = new LinkedHashMap(); paramMappings.put(comp.getUniqueID(), paramMappingsComp); } - - for (Property prop: comp.getComponentType().getPropertys()) + + for (Property prop: comp.getComponentType().getPropertys()) { if(comp.getComponentType().isOrExtends(NeuroMLElements.GAP_JUNCTION) || comp.getComponentType().isOrExtends(NeuroMLElements.BASE_GRADED_SYNAPSE)|| @@ -3133,7 +3213,7 @@ private void parseParameters(Component comp, String prefix, String prefixParent, String mappedName = prefix + prop.getName(); rangeVars.add(mappedName); paramMappingsComp.put(prop.getName(), mappedName); - + String range = "RANGE " + mappedName; while(range.length() < NRNUtils.commentOffset) { @@ -3170,7 +3250,12 @@ private void parseParameters(Component comp, String prefix, String prefixParent, { valS = (int) val + ""; } - blockParameter.append("\n" + mappedName + " = " + valS + " " + NRNUtils.getNeuronUnit(pv.getDimensionName())); + String d = "\n" + mappedName + " = " + valS + " " + NRNUtils.getNeuronUnit(pv.getDimensionName()); + while(d.length() < NRNUtils.commentOffset) + { + d = d + " "; + } + blockParameter.append(d + ": was: "+pv.getDoubleValue() +" (" +pv.getDimensionName()+")"); } for(Exposure exp : comp.getComponentType().getExposures()) @@ -3182,12 +3267,12 @@ private void parseParameters(Component comp, String prefix, String prefixParent, rangeVars.add(mappedName); paramMappingsComp.put(exp.getName(), mappedName); - String range = "\nRANGE " + mappedName; + String range = "RANGE " + mappedName; while(range.length() < NRNUtils.commentOffset) { range = range + " "; } - blockNeuron.append(range + " : exposure\n"); + blockNeuron.append(range + ": exposure\n"); if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_SYNAPSE_COMP_TYPE) && exp.getName().equals(NeuroMLElements.POINT_CURR_CURRENT) && @@ -3228,7 +3313,7 @@ private void parseParameters(Component comp, String prefix, String prefixParent, } } ArrayList orderedChildren = comp.getAllChildren(); - + for(Component childComp : orderedChildren) { String prefixNew = getPrefix(childComp, prefix); @@ -3238,10 +3323,10 @@ private void parseParameters(Component comp, String prefix, String prefixParent, } } - if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_CELL_COMP_TYPE)) + /*if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_CELL_COMP_TYPE)) { - blockNeuron.append("\nRANGE " + NRNUtils.V_COPY_PREFIX + NRNUtils.NEURON_VOLTAGE + " : copy of v on section\n"); - } + blockNeuron.append("\nRANGE " + NRNUtils.V_COPY_PREFIX + NRNUtils.NEURON_VOLTAGE + " : copy of v on section\n"); + }*/ } @@ -3280,13 +3365,14 @@ private void parseStateVars(Component comp, String prefix, ArrayList ran if(sv.getName().equals(NRNUtils.NEURON_VOLTAGE)) { - blockNeuron.append("\n\nNONSPECIFIC_CURRENT i : To ensure v of section follows " + svName + "\n"); + blockNeuron.append("\n\nNONSPECIFIC_CURRENT i : To ensure v of section follows " + svName + "\n"); blockAssigned.append("v (mV)\n"); - blockAssigned.append("i (mA/cm2)\n\n"); + blockAssigned.append("i (nA) : the point process current \n\n"); + //blockAssigned.append("i (mA/cm2) : point process current \n\n"); - blockAssigned.append(NRNUtils.V_COPY_PREFIX + NRNUtils.NEURON_VOLTAGE + " (mV)\n\n"); + //blockAssigned.append(NRNUtils.V_COPY_PREFIX + NRNUtils.NEURON_VOLTAGE + " (mV)\n\n"); - dim = "(nA)"; + dim = "(mV/ms) : for rate of change of voltage"; } String bounds = ""; if (comp.getComponentType().isOrExtends(NeuroMLElements.KS_STATE_COMP_TYPE)) { @@ -3299,11 +3385,11 @@ private void parseStateVars(Component comp, String prefix, ArrayList ran } else if(Arrays.asList(NRNUtils.NON_NRN_STATE_VARS).contains(sv.getName())) { - blockAssigned.append(svName +bounds + " "+ dim + " : Not a state variable as far as Neuron's concerned..."+"\n"); + blockAssigned.append(svName +bounds + " "+ dim + " : Not a state variable as far as Neuron's concerned..."+"\n"); } else { - blockState.append(svName +bounds + " "+ dim + " "+"\n"); + blockState.append(svName +bounds + " "+ dim + " : dimension: "+sv.getDimension().getName()+"\n"); } } } @@ -3372,7 +3458,7 @@ private void parseTimeDerivs(Component comp, String prefix, ArrayList lo String stateVarToUse = NRNUtils.getStateVarName(td.getStateVariable().getName()); String line = prefix + stateVarToUse + "' = " + rateName; - + if(comp.getComponentType().isOrExtends(NeuroMLElements.CONC_MODEL_COMP_TYPE) && td.getStateVariable().getName().equals(NeuroMLElements.CONC_MODEL_CONC_STATE_VAR)) { @@ -3499,7 +3585,7 @@ private void parseDerivedVars(Component comp, String prefix, ArrayList r String prefixNew = getPrefix(childComp, prefix); parseDerivedVars(childComp, prefixNew, rangeVars, ratesMethod, blockNeuron, blockParameter, blockAssigned, blockBreakpoint, paramMappings); } - + ArrayList instanceRequirements = new ArrayList(); for(InstanceRequirement ir : comp.getComponentType().instanceRequirements) { @@ -3527,7 +3613,7 @@ private void parseDerivedVars(Component comp, String prefix, ArrayList r { blockNeuron.append("POINTER " + dv.getName() + ": derived variable as pointer...\n"); } - else + else { blockNeuron.append("RANGE " + dv.getName() + ": derived variable; RANGE, not POINTER for Parallel NEURON...\n"); } @@ -3546,7 +3632,7 @@ else if(!rangeVars.contains(mappedName)) paramMappingsComp.put(dv.getName(), mappedName); } - String assig = "\n" + prefix + dv.getName() + " " + NRNUtils.getNeuronUnit(dv.dimension); + String assig = prefix + dv.getName() + " " + NRNUtils.getNeuronUnit(dv.dimension); while(assig.length() < NRNUtils.commentOffset) { assig = assig + " "; @@ -3648,15 +3734,15 @@ else if (localVar.startsWith("ionChannel_")) { localVar = localVar.replaceFirst("ionChannel_", comp.getChild("ionChannel").getID()+"_"); } - + String globalVar = prefix + localVar; String eqn = globalVar; String comment = ""; - + if(comp.getComponentType().isOrExtends(NeuroMLElements.BASE_RATE_UNIT) && globalVar.toLowerCase().contains("syn")) { - eqn = "isyn_in * 3.14159 ? Using this value, which comes from i_cap on the cell via a pointer, for the synaptic current" ; + eqn = "isyn_in * 3.14159 ? Using this value, which comes from i_cap on the cell via a pointer, for the synaptic current" ; } else if(globalVar.contains("[*]") && globalVar.contains("syn")) { @@ -3720,13 +3806,13 @@ else if(localVar.contains("[*]")) paramMappingsComp.put(cdv.getName(), mappedName); } - String assig = "\n" + prefix + cdv.getName() + " " + NRNUtils.getNeuronUnit(cdv.dimension); + String assig = prefix + cdv.getName() + " " + NRNUtils.getNeuronUnit(cdv.dimension); while(assig.length() < NRNUtils.commentOffset) { assig = assig + " "; } - blockAssigned.append(assig + ": conditional derived var...\n"); + blockAssigned.append("\n" + assig + ": conditional derived var...\n"); for(Case c : cdv.cases) { @@ -3770,7 +3856,7 @@ public class CompInfo StringBuilder eqns = new StringBuilder(); StringBuilder initInfo = new StringBuilder(); } - + /* * Can be used to generate Neuron hoc/mod files for cells (with channels) and synapses */ @@ -3810,7 +3896,7 @@ else if (comp.getComponentType().isOrExtends(NeuroMLElements.CONC_MODEL_COMP_TYP foundMods = true; } // TODO: more..? - + } if (compileMods && foundMods) { @@ -3833,12 +3919,12 @@ public static void main(String[] args) throws Exception MinimalMessageHandler.setVeryMinimal(true); E.setDebug(false); - + ArrayList nmlFiles = new ArrayList(); nmlFiles.add(new File("../NeuroML2/examples/NML2_SingleCompHHCell.nml")); nmlFiles.add(new File("../NeuroML2/examples/NML2_SynapseTypes.nml")); //nmlFiles.add(new File("../git/BonoClopath2017/NeuroML2/SimpleNet.net.nml")); - + for(File nmlFile : nmlFiles) { Lems lems = Utils.readNeuroMLFile(nmlFile.getAbsoluteFile()).getLems(); @@ -3847,9 +3933,11 @@ public static void main(String[] args) throws Exception nw.generateFilesForNeuroMLElements(false); } //System.exit(0); - + 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/showcase/StochasticityShowcase/NeuroML2/LEMS_Inputs0.xml")); //lemsFiles.add(new File("../neuroConstruct/osb/invertebrate/celegans/CElegansNeuroML/CElegans/pythonScripts/c302/examples/LEMS_c302_C1_Oscillator.xml")); @@ -3858,20 +3946,21 @@ public static void main(String[] args) throws Exception //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex16_Inputs.xml")); //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("../org.neuroml.export/src/test/resources/examples/LEMS_SpikePass2.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("../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_2007One.xml")); - lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/IzhikevichModel/NeuroML2/LEMS_FiveCells.xml")); - //lemsFiles.add(new File("../git/TestHippocampalNetworks/NeuroML2/channels/test_Cadynamics/NeuroML2/LEMS_test_Ca.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("../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")); //lemsFiles.add(new File("../NeuroMLlite/examples/test_files/test_inputs/LEMS_InputTest.xml")); //lemsFiles.add(new File("../NeuroMLlite/neuromllite/LEMS_Sim_NML2_300_pointneurons.xml")); - + // //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex26_Weights.xml")); //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex19_GapJunctions.xml")); @@ -3882,9 +3971,9 @@ public static void main(String[] args) throws Exception //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex27_MultiSynapses.xml")); //lemsFiles.add(new File("../neuroConstruct/osb/generic/hodgkin_huxley_tutorial/Tutorial2/NeuroML2/LEMS_HHTutorial.xml")); //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/neocortical_pyramidal_neuron/SmithEtAl2013-L23DendriticSpikes/NeuroML2/LEMS_L23_Stim.xml")); - + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex19a_GapJunctionInstances.xml")); -// +// // 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")); @@ -3892,9 +3981,9 @@ public static void main(String[] args) throws Exception // //lemsFiles.add(new File("../OpenCortex/examples/LEMS_SpikingNet.xml")); // lemsFiles.add(new File("../OpenCortex/examples/LEMS_SimpleNet.xml")); -// +// // lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/IzhikevichModel/NeuroML2/LEMS_2007One.xml")); - + // lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex20a_AnalogSynapsesHH.xml")); //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex14_PyNN.xml")); // lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/multiple/PospischilEtAl2008/NeuroML2/cells/RS/LEMS_RS.xml")); @@ -3902,15 +3991,15 @@ public static void main(String[] args) throws Exception //lemsFiles.add(new File("../git/del-Molino2017/NeuroML/Fig1/LEMS_RateBased_low_baseline.xml")); //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/WilsonCowan/NeuroML2/LEMS_WC_driven.xml")); //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/MejiasEtAl2016/NeuroML2/LEMS_Test.xml")); - + // 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")); - + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/networks/ACnet2/neuroConstruct/generatedNeuroML2/LEMS_StimuliTest.xml")); //lemsFiles.add(new File("../git/alex-neuroml-test/LEMS_sim.xml")); //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex6_NMDA.xml")); @@ -3918,15 +4007,15 @@ public static void main(String[] args) throws Exception /* lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/LEMS_M1.xml")); lemsFiles.add(new File("../git/NML2_Test/AOB_mitral_cell/LEMS_Vm_iMC1_cell_1_origin.xml")); - + //lemsFiles.add(new File("../neuroConstruct/osb/cerebral_cortex/neocortical_pyramidal_neuron/L5bPyrCellHayEtAl2011/neuroConstruct/generatedNeuroML2/LEMS_TestL5PC.xml")); - + //lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex7_STP.xml")); - + lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex5_DetCell.xml")); lemsFiles.add(new File("../neuroConstruct/osb/cerebellum/cerebellar_granule_cell/GranuleCell/neuroConstruct/generatedNeuroML2/LEMS_GranuleCell.xml")); - + lemsFiles.add(new File("../neuroConstruct/osb/cerebellum/networks/GranCellLayer/neuroConstruct/generatedNeuroML2/LEMS_GranCellLayer.xml")); lemsFiles.add(new File("../neuroConstruct/osb/cerebellum/cerebellar_golgi_cell/SolinasEtAl-GolgiCell/NeuroML2/LEMS_Soma_Test_HELPER.xml")); @@ -3988,12 +4077,12 @@ public static void main(String[] args) throws Exception lemsFiles.add(new File("../neuroConstruct/osb/invertebrate/celegans/CElegansNeuroML/CElegans/pythonScripts/c302/examples/LEMS_c302_B_Social.xml")); /* - + lemsFiles.add(new File("../neuroConstruct/osb/showcase/NetPyNEShowcase/NeuroML2/chanDens/LEMS_cck.xml")); - + lemsFiles.add(new File("../NeuroML2/LEMSexamples/LEMS_NML2_Ex1_HH.xml")); lemsFiles.add(new File("../neuroConstruct/osb/cerebellum/cerebellar_granule_cell/GranuleCell/neuroConstruct/generatedNeuroML2/LEMS_GranuleCell.xml")); */ - + String testScript = "set -e\n"; NeuronWriter nw; diff --git a/src/main/java/org/neuroml/export/neuron/ProcessManager.java b/src/main/java/org/neuroml/export/neuron/ProcessManager.java index 4713ba23a..645a55c81 100644 --- a/src/main/java/org/neuroml/export/neuron/ProcessManager.java +++ b/src/main/java/org/neuroml/export/neuron/ProcessManager.java @@ -34,13 +34,17 @@ public static File findNeuronHome() throws NeuroMLException String nrnEnvVar = System.getenv(NeuronWriter.NEURON_HOME_ENV_VAR); String[] knownVersions = new String[] { - "7.5", "7.4", "7.3", "7.2", "7.1", "6.2", "6.1", "6.0" + "8.2.1", "8.2.0", "8.1.0", "8.0.2", "8.0.1", "8.0.0", + "7.8.2", "7.8.1", "7.7.1", "7.6.7", "7.5", "7.4", "7.3", "7.2", "7.1", + "6.2", "6.1", "6.0" }; - if (nrnEnvVar != null) + /* If NEURON_HOME is defined, it gets priority */ + if (nrnEnvVar != null && nrnEnvVar.length()>0) { options.add(nrnEnvVar); } + /* If NEURON_HOME is not defined, check all the usual suspects */ else if (Utils.isWindowsBasedPlatform()) { for (String ver : knownVersions) @@ -52,6 +56,12 @@ else if (Utils.isWindowsBasedPlatform()) } else if (Utils.isMacBasedPlatform()) { + /* Check folders in PATH */ + for (String folder: System.getenv("PATH").split(";")) { + options.add(folder); + } + + /* Other possible folders */ for (String ver : knownVersions) { options.add("/Applications/NEURON-" + ver + "/nrn/powerpc"); @@ -63,6 +73,13 @@ else if (Utils.isMacBasedPlatform()) } else if (Utils.isLinuxBasedPlatform()) { + + /* Check folders in PATH */ + for (String folder: System.getenv("PATH").split(":")) { + options.add(folder); + } + + /* Other possible folders */ options.add("/usr"); options.add("/usr/local"); options.add("/usr/local/nrn/x86_64"); @@ -81,10 +98,10 @@ else if (Utils.isLinuxBasedPlatform()) return new File(option); } } - + String env = Utils.sysEnvInfo(" "); - throw new NeuroMLException("Could not find NEURON home directory! Options tried: " + options + throw new NeuroMLException("Could not find NEURON home directory! Options tried here: " + options + "\nThe NEURON executable which is sought inside this directory is: " + nrnExe + ". \n\n" + "Try setting the environment variable " + NeuronWriter.NEURON_HOME_ENV_VAR + " to the location of your NEURON installation (up to but not including bin), e.g.\n\n" @@ -144,7 +161,7 @@ public static boolean compileFileWithNeuron(File modDirectory, boolean forceReco File modCompileScript = Utils.copyFromJarToTempLocation("/neuron/mknrndll.sh"); - String shFriendlyPath = + String shFriendlyPath = modCompileScript.getAbsolutePath().replaceAll("c:\\\\", "/cygdrive/c/").replaceAll("C:\\\\", "/cygdrive/c/").replaceAll("\\\\", "/"); if (binExe.indexOf("mingw") > 0) @@ -201,19 +218,39 @@ public static boolean compileFileWithNeuron(File modDirectory, boolean forceReco E.info("Name of file to be created: " + filename2); } + /* *.so in .libs */ + filename1 = directoryToExecuteIn + System.getProperty("file.separator") + myArch + System.getProperty("file.separator") + ".libs" + System.getProperty("file.separator") + "libnrnmech.so"; + filesToBeCreated.add(new File(filename1)); + E.info("Name of file to be created: " + filename1); + + // In case, e.g. a 32 bit JDK is used on a 64 bit system + filename2 = directoryToExecuteIn + System.getProperty("file.separator") + backupArchDir + System.getProperty("file.separator") + ".libs" + System.getProperty("file.separator") + "libnrnmech.so"; + /* Only add if it does not already exist: prevent duplication */ + if (!filename1.equals(filename2)){ + filesToBeCreated.add(new File(filename2)); + E.info("Name of file to be created: " + filename2); + } + /** * @todo Needs checking on Mac/powerpc/i686 */ if (Utils.isMacBasedPlatform()) { - String filename = directoryToExecuteIn + System.getProperty("file.separator") + Utils.getArchSpecificDir() + System.getProperty("file.separator") + "libnrnmech.la"; - E.info("Name of file to be created: " + filename); - filesToBeCreated.add(new File(filename)); + filename1 = directoryToExecuteIn + System.getProperty("file.separator") + Utils.getArchSpecificDir() + System.getProperty("file.separator") + "libnrnmech.la"; + E.info("Name of file to be created 1: " + filename1); + filesToBeCreated.add(new File(filename1)); + + filename1 = directoryToExecuteIn + System.getProperty("file.separator") + "umac" + System.getProperty("file.separator") + "libnrnmech.la"; + E.info("Name of file to be created 2: " + filename1); + filesToBeCreated.add(new File(filename1)); - filename = directoryToExecuteIn + System.getProperty("file.separator") + "umac" + System.getProperty("file.separator") + "libnrnmech.la"; - E.info("Name of file to be created: " + filename); - filesToBeCreated.add(new File(filename)); + filename1 = directoryToExecuteIn + System.getProperty("file.separator") + Utils.getArchSpecificDir() + System.getProperty("file.separator") + "libnrnmech.dylib"; + E.info("Name of file to be created 3: " + filename1); + filesToBeCreated.add(new File(filename1)); + filename1 = directoryToExecuteIn + System.getProperty("file.separator") + "arm64" + System.getProperty("file.separator") + "libnrnmech.dylib"; + E.info("Name of file to be created 4: " + filename1); + filesToBeCreated.add(new File(filename1)); } commandToExecute = neuronHome.getCanonicalPath() + System.getProperty("file.separator") + "bin" + System.getProperty("file.separator") + "nrnivmodl"; @@ -332,8 +369,7 @@ public static boolean compileFileWithNeuron(File modDirectory, boolean forceReco { E.info("Compilation failed. Unable to find necessary file(s)." + " Please note that Neuron checks every *.mod file in this file's parent directory\n" + - "(" + modDirectory + ").\n" + - "For more information when this error occurs, enable logging at Settings -> General Properties & Project Defaults -> Logging\n\n" + + "(" + modDirectory + ").\n\n" + linMacWarn); /* Print list of files we look for */ diff --git a/src/main/java/org/neuroml/export/pynn/PyNNWriter.java b/src/main/java/org/neuroml/export/pynn/PyNNWriter.java index 30fe2dddd..56c99090d 100644 --- a/src/main/java/org/neuroml/export/pynn/PyNNWriter.java +++ b/src/main/java/org/neuroml/export/pynn/PyNNWriter.java @@ -273,7 +273,7 @@ public static void main(String[] args) throws Exception //lemsFiles.add(new File("../OpenCortex/examples/LEMS_Complex.xml")); //lemsFiles.add(new File("../OpenCortex/examples/LEMS_IClamps.xml")); lemsFiles.add(new File("../OpenCortex/examples/LEMS_Deterministic.xml")); - //lemsFiles.add(new File("../neuroConstruct/osb/showcase/PyNNShowcase/NeuroML2/LEMS_2007One.xml")); + lemsFiles.add(new File("../neuroConstruct/osb/showcase/PyNNShowcase/NeuroML2/LEMS_2007One.xml")); lemsFiles.add(new File("../neuroConstruct/osb/generic/hodgkin_huxley_tutorial/Tutorial/Source/LEMS_HH_SingleAP.xml")); lemsFiles.add(new File("../neuroConstruct/osb/invertebrate/celegans/muscle_model/NeuroML2/LEMS_MuscleStim.xml")); @@ -282,8 +282,8 @@ public static void main(String[] args) throws Exception Lems lems = Utils.readLemsNeuroMLFile(lemsFile).getLems(); PyNNWriter pw = new PyNNWriter(lems, lemsFile.getParentFile(), lemsFile.getName().replaceAll(".xml", "_pynn.py")); boolean runNrn = true; - //List files = pw.generateAndRun(false, runNrn); - List files = pw.convert(); + List files = pw.generateAndRun(false, runNrn); + //List files = pw.convert(); for (File f : files) { System.out.println("Have created: " + f.getAbsolutePath()); diff --git a/src/main/java/org/neuroml/export/sbml/SBMLWriter.java b/src/main/java/org/neuroml/export/sbml/SBMLWriter.java index bf84281d4..644933abe 100644 --- a/src/main/java/org/neuroml/export/sbml/SBMLWriter.java +++ b/src/main/java/org/neuroml/export/sbml/SBMLWriter.java @@ -228,7 +228,7 @@ public String getMainScript() throws GenerationException for(DerivedVariable dv : type.getDynamics().getDerivedVariables()) { startElement(main, "assignmentRule", "variable=" + dv.getName()); - System.out.println(dv.getName()+" = "+dv.getFunc()); + //System.out.println(dv.getName()+" = "+dv.getFunc()); processMathML(main, dv.getParseTree()); endElement(main, "assignmentRule"); } diff --git a/src/main/java/org/neuroml/export/utils/Format.java b/src/main/java/org/neuroml/export/utils/Format.java index f697128f5..b41b2f46c 100644 --- a/src/main/java/org/neuroml/export/utils/Format.java +++ b/src/main/java/org/neuroml/export/utils/Format.java @@ -21,6 +21,7 @@ public enum Format PYNN("PyNN", "py"), NETPYNE("NETPYNE", "py"), MOOSE("MOOSE", "py"), + EDEN("EDEN", "py"), SVG("SVG", "svg"), NINEML("NineML", "9ml"), SPINEML("SpineML", "spineml"), @@ -29,9 +30,9 @@ public enum Format XINEML("Xineml", ""), XPP("Xpp", "ode"), PNG("PNG", "png"), - VERTEX("VERTEX", "m"), + VERTEX("VERTEX", "m"), JNEUROML("jNeuroML", "xml"); - + private final String label; private final String extension; @@ -40,7 +41,7 @@ private Format(String label, String extension) this.label = label; this.extension = extension; } - + public String getExtension() { return extension; @@ -50,13 +51,13 @@ public String getLabel() { return label; } - + @Override public String toString() { return label; } - - + + } diff --git a/src/main/java/org/neuroml/export/utils/Utils.java b/src/main/java/org/neuroml/export/utils/Utils.java index 6bdb36b82..29f14ece4 100644 --- a/src/main/java/org/neuroml/export/utils/Utils.java +++ b/src/main/java/org/neuroml/export/utils/Utils.java @@ -42,7 +42,7 @@ public class Utils private static Lems lemsWithNML2CompTypes; - public static String ORG_NEUROML_EXPORT_VERSION = "1.8.1"; + public static String ORG_NEUROML_EXPORT_VERSION = "1.9.1"; public static final String ARCH_I686 = "i686"; public static final String ARCH_I386 = "i386"; diff --git a/src/main/java/org/neuroml/export/utils/VelocityUtils.java b/src/main/java/org/neuroml/export/utils/VelocityUtils.java index 4211c136b..080ab0ecc 100644 --- a/src/main/java/org/neuroml/export/utils/VelocityUtils.java +++ b/src/main/java/org/neuroml/export/utils/VelocityUtils.java @@ -12,64 +12,66 @@ public class VelocityUtils { public static final String neuronCellTemplateFile = "/neuron/cell.vm"; - + public static final String modelicaClassTemplateFile = "/modelica/main_class.vm"; public static final String modelicaRunTemplateFile = "/modelica/run.vm"; - + // public static final String sbmlTemplateFile = "/sbml/template.sbml"; - + public static final String mooseRunTemplateFile = "/moose/run.vm"; - + + public static final String edenRunTemplateFile = "/eden/run.vm"; + public static final String nestRunTemplateFile = "/nest/run.vm"; public static final String nestCellTemplateFile = "/nest/cell.vm"; - + public static final String pynnRunTemplateFile = "/pynn/run.vm"; public static final String pynnAbstractCellTemplateFile = "/pynn/abstract_cell.vm"; public static final String pynnMorphCellTemplateFile = "/pynn/morph_cell.vm"; public static final String pynnInputNeuronTemplateFile = "/pynn/input_neuron.vm"; - + public static final String netpyneRunTemplateFile = "/netpyne/run.vm"; public static final String netpyneCellTemplateFile = "/netpyne/cell.vm"; public static final String netpyneInputNeuronTemplateFile = "/netpyne/input_neuron.vm"; - + public static final String cTemplateFile = "/cvode/cvode.vm"; public static final String makeFile = "cvode/Makefile"; - + public static final String matlabOdeFile = "/matlab/matlab_ode.vm"; public static final String matlabEulerFile = "/matlab/matlab_euler.vm"; - + public static final String dnsimMainFile = "/dnsim/dnsim.m.vm"; public static final String dnsimModuleFile = "/dnsim/dnsim.txt.vm"; - + public static final String vertexRunTemplateFile = "/vertex/run.vm"; public static final String vertexCellTemplateFile = "/vertex/cell.vm"; public static final String vertexSynapseTemplateFile = "/vertex/synapse.vm"; - + public static final String xppTemplateFile = "/xpp/xpp.vm"; - - + + public static void initializeVelocity(){ Properties props = new Properties(); - //FIXME: This line removes any log system in velocity. We need this for Geppetto but eventually a proper log system is needed - props.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, NullLogChute.class.getName()); + //FIXME: This line removes any log system in velocity. We need this for Geppetto but eventually a proper log system is needed + props.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, NullLogChute.class.getName()); Velocity.init(props); } - + public static VelocityEngine getVelocityEngine(){ Properties propsEngine = new Properties(); propsEngine.put("resource.loader", "classpath"); propsEngine.put("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); //FIXME: This line removes any log system in velocity. We need this for Geppetto but eventually a proper log system is needed - propsEngine.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, NullLogChute.class.getName()); + propsEngine.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, NullLogChute.class.getName()); VelocityEngine ve = new VelocityEngine(); ve.init(propsEngine); return ve; } - + public static Reader getTemplateAsReader(String path){ InputStream inputStream = VelocityUtils.class.getResourceAsStream(path); Reader reader = new InputStreamReader(inputStream); return reader; - + } } diff --git a/src/main/resources/eden/run.vm b/src/main/resources/eden/run.vm new file mode 100644 index 000000000..b33f62273 --- /dev/null +++ b/src/main/resources/eden/run.vm @@ -0,0 +1,17 @@ +# Main EDEN script for: $name + +import eden_simulator +import sys + +filename = '${main_lems_file}' +print( + "Running a simulation of %s in EDEN v%s" + % ( + filename, + eden_simulator.__version__ if hasattr(eden_simulator, "__version__") else "???", + ) +) + +results = eden_simulator.runEden(filename) + +print("Completed simulation in EDEN, saved results: %s"%(results.keys())) diff --git a/src/main/resources/netpyne/run.vm b/src/main/resources/netpyne/run.vm index 39e8df983..8ed746ee5 100644 --- a/src/main/resources/netpyne/run.vm +++ b/src/main/resources/netpyne/run.vm @@ -14,7 +14,7 @@ import datetime class NetPyNESimulation(): - def __init__(self, tstop, dt, seed=123456789, save_json=False): + def __init__(self, tstop=$t_end, dt=$dt, seed=123456789, save_json=False): self.setup_start = time.time() #if ($report_file) @@ -27,6 +27,7 @@ class NetPyNESimulation(): self.report_file.write('PythonVersion=%s\n'%sys.version.replace('\n',' ')) self.report_file.write('NeuronVersion=%s\n'%h.nrnversion()) self.report_file.write('NeuroMLExportVersion=$export_library_version\n') + self.report_file.close() #end @@ -49,22 +50,22 @@ class NetPyNESimulation(): # Seeds for randomizers (connectivity, input stimulation and cell locations) # Note: locations and connections should be fully specified by the structure of the NeuroML, # so seeds for conn & loc shouldn't affect networks structure/behaviour - self.simConfig.seeds = {'conn': 0, 'stim': $seed, 'loc': 0} + self.simConfig.seeds = {'conn': 0, 'stim': $seed, 'loc': 0} self.simConfig.createNEURONObj = 1 # create HOC objects when instantiating network self.simConfig.createPyStruct = 1 # create Python structure (simulator-independent) when instantiating network - self.simConfig.verbose = False # show detailed messages + self.simConfig.verbose = False # show detailed messages #if ($temperature) self.simConfig.hParams['celsius'] = ($temperature - 273.15) #end - # Recording - self.simConfig.recordCells = ['all'] + # Recording + self.simConfig.recordCells = ['all'] self.simConfig.recordTraces = {} self.simConfig.saveCellSecs=False self.simConfig.saveCellConns=False - self.simConfig.gatherOnlySimData=True + self.simConfig.gatherOnlySimData=True #foreach ($of in $output_file ) # For saving to file: $of.file_name (ref: $of.name) @@ -122,15 +123,40 @@ class NetPyNESimulation(): print("Exception saving results of NetPyNE simulation: %s" % (e)) return + def generate_json_only(self): + + #[[###############################################################################]]# + # GENERATE NETPYNE JSON REPRESENTATION OF NETWORK + #[[###############################################################################]]# + + print("Generating NetPyNE JSON (and mod files)") + + self.simConfig.saveJson = True # save to json file + from netpyne.conversion.neuromlFormat import importNeuroML2 + self.gids = sim.importNeuroML2(self.nml2_file_name, + self.simConfig, + simulate=False, + analyze=False) + + from netpyne.sim.save import saveData + + json_filename=__file__.replace(".py","") + saveData(filename=json_filename, include=["simConfig", "netParams", "net"]) + real_json_filename='%s_data.json'%json_filename + + print("Finished exporting the NetPyNE JSON to %s"%real_json_filename) + + return real_json_filename + def save_results(self): #[[###############################################################################]]# - # Saving data (this ensures the data gets saved in the format/files + # Saving data (this ensures the data gets saved in the format/files # as specified in the LEMS element) #[[###############################################################################]]# - if sim.rank==0: + if sim.rank==0: #foreach ($of in $output_file ) print("Saving traces to file: $of.file_name (ref: $of.name)") @@ -191,7 +217,8 @@ class NetPyNESimulation(): #if ($report_file) - + + self.report_file = open('$report_file','a') self.report_file.write('StartTime=%s\n'%datetime.datetime.fromtimestamp(self.setup_start).strftime('%Y-%m-%d %H:%M:%S')) self.report_file.write('RealSetupAndSimulationTime=%s\n'%self.setup_sim_time) self.report_file.write('SimulationSaveTime=%s\n'%save_time) @@ -202,10 +229,17 @@ class NetPyNESimulation(): if __name__ == '__main__': save_json = '-json' in sys.argv + no_run = '-norun' in sys.argv ns = NetPyNESimulation(tstop=$t_end, dt=$dt, seed=$seed, save_json=save_json) - ns.run() + if not no_run: + ns.run() + else: + if save_json: + fn = ns.generate_json_only() + print("Generated: %s"%fn) + quit() if '-nogui' in sys.argv: quit() diff --git a/src/main/resources/pynn/abstract_cell.vm b/src/main/resources/pynn/abstract_cell.vm index f4f5ce447..001b4d8ee 100644 --- a/src/main/resources/pynn/abstract_cell.vm +++ b/src/main/resources/pynn/abstract_cell.vm @@ -20,7 +20,7 @@ class $name(object): self.soma(0.5).diam = 10.0 # Todo: work this out here from area etc. # See https://github.com/NeuroML/org.neuroml.export/issues/60 - self.soma(0.5).cm = (318310*parameters['C'] if 'C' in parameters else 318.31 ) + self.soma(0.5).cm = (318.310*parameters['C'] if 'C' in parameters else 318.31 ) self.soma.push() self.mechanism = h.$name(0.5, sec=self.soma) diff --git a/src/test/java/org/neuroml/export/neuron/NRNUtilsTest.java b/src/test/java/org/neuroml/export/neuron/NRNUtilsTest.java new file mode 100644 index 000000000..0ace11bb4 --- /dev/null +++ b/src/test/java/org/neuroml/export/neuron/NRNUtilsTest.java @@ -0,0 +1,54 @@ +package org.neuroml.export.neuron; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import junit.framework.TestCase; +import org.lemsml.jlems.core.logging.MinimalMessageHandler; +import org.lemsml.jlems.core.sim.LEMSException; +import org.lemsml.jlems.core.type.Component; +import org.lemsml.jlems.core.type.Lems; +import org.lemsml.jlems.io.util.FileUtil; +import org.neuroml.export.exceptions.GenerationException; +import org.neuroml.export.exceptions.ModelFeatureSupportException; +import org.neuroml.export.utils.Utils; +import org.neuroml.model.Cell; +import org.neuroml.model.NeuroMLDocument; +import org.neuroml.model.util.NeuroMLConverter; +import org.neuroml.model.util.NeuroMLException; +import org.lemsml.jlems.core.type.DimensionalQuantity; +import org.lemsml.jlems.core.type.QuantityReader; +import java.util.*; + +public class NRNUtilsTest extends TestCase { + + + public void testUnits() throws LEMSException, IOException, GenerationException, NeuroMLException, ModelFeatureSupportException { + + + List nrnVals = Arrays.asList("1", "1mV","1ms","1per_mV","1per_ms","1uS","1cm","1cm2","1cm3", + "1nA","1uS_per_cm2","1mA_per_cm2", "1nF", "1pC_per_umol", + "1umol_per_cm_per_nA_per_ms", "1fJ_per_K_per_umol"); + + for (String nrnVal : nrnVals) { + float si = Utils.getMagnitudeInSI(nrnVal); + String dim = Utils.getDimension(nrnVal).getName(); + float nrnSi = NRNUtils.convertToNeuronUnits(1, dim); + float exp = 1/si; + + System.out.println("Checking "+nrnVal+" = "+si+" "+dim+" in SI; so 1 in SI should be "+exp+", is "+nrnSi+" "+NRNUtils.getNeuronUnit(dim)); + + assertEquals(exp, nrnSi, nrnSi*0.0001); + } + + + //assertEquals(x*1000, NRNUtils.convertToNeuronUnits(x, "conductanceDensity")); + + } + public static void main(String args[]) throws LEMSException, IOException, GenerationException, NeuroMLException, ModelFeatureSupportException + { + NRNUtilsTest n = new NRNUtilsTest(); + n.testUnits(); + } + +} diff --git a/src/test/java/org/neuroml/export/sbml/SBMLWriterTest.java b/src/test/java/org/neuroml/export/sbml/SBMLWriterTest.java index 930095aa2..c1b156764 100644 --- a/src/test/java/org/neuroml/export/sbml/SBMLWriterTest.java +++ b/src/test/java/org/neuroml/export/sbml/SBMLWriterTest.java @@ -32,18 +32,18 @@ public void testGetMainScript1() throws LEMSException, IOException, GenerationEx }/* * public void testGetMainScript2() throws ContentError, ParseError, ParseException, BuildException, XMLException, IOException, SAXException, ConnectionError, RuntimeError, GenerationException { - * + * * String exampleFilename = "/home/padraig/git/HindmarshRose1984/NeuroML2/Run_Regular_HindmarshRose.xml"; Lems lems = Utils.readLemsNeuroMLFile(new File(exampleFilename)).getLems(); * generateSBMLAndTestScript(lems, "Run_Regular_HindmarshRose.xml"); - * + * * } - * + * * public void testGetMainScript3() throws ContentError, ParseError, ParseException, BuildException, XMLException, IOException, SAXException, ConnectionError, RuntimeError { - * + * * String exampleFilename = "LEMS_NML2_Ex0_IaF.xml"; Lems lems = AppTest.readLemsFileFromExamples(exampleFilename); - * + * * generateSBMLAndTestScript(lems, exampleFilename); - * + * * } */ @@ -52,7 +52,7 @@ public void generateSBMLAndTestScript(Lems lems, String exampleFileName) throws SBMLWriter sbmlw = new SBMLWriter(lems, UtilsTest.getTempDir(), exampleFileName.replaceAll("xml", "sbml")); List outputFiles = sbmlw.convert(); - + UtilsTest.checkConvertedFiles(outputFiles); NeuroML2Validator.testValidity(outputFiles.get(0), LOCAL_SBML_SCHEMA);