diff --git a/models/aeif_cond_alpha.nestml b/models/aeif_cond_alpha.nestml index 25b1a65fa..5cbe66101 100644 --- a/models/aeif_cond_alpha.nestml +++ b/models/aeif_cond_alpha.nestml @@ -38,7 +38,7 @@ neuron aeif_cond_alpha_neuron: end equations: - V_bounded mV = min(V_m, V_peak) # prevent exponential divergence + V_bounded mV = bounded_min(V_m, V_peak) # prevent exponential divergence shape g_in = (e/tau_syn_in) * t * exp(-1/tau_syn_in*t) shape g_ex = (e/tau_syn_ex) * t * exp(-1/tau_syn_ex*t) diff --git a/models/aeif_cond_alpha_implicit.nestml b/models/aeif_cond_alpha_implicit.nestml index 1d29f6d68..3bbf25f1d 100644 --- a/models/aeif_cond_alpha_implicit.nestml +++ b/models/aeif_cond_alpha_implicit.nestml @@ -42,12 +42,12 @@ neuron aeif_cond_alpha_implicit: equations: V_bounded mV = min(V_m, V_peak) # prevent exponential divergence # alpha function for the g_in - g_in'' = -g_in'/tau_syn_in - g_in' = g_in' - g_in/tau_syn_in + g_in'' = (-2/tau_syn_in) * g_in'-(1/tau_syn_in**2) * g_in + g_in' = g_in' # alpha function for the g_ex - g_ex'' = -g_ex'/tau_syn_ex - g_ex' = g_ex' - g_ex/tau_syn_ex + g_ex'' = (-2/tau_syn_ex) * g_ex'-(1/tau_syn_ex**2) * g_ex + g_ex' = g_ex' # Add aliases to simplify the equation definition of V_m exp_arg real = (V_bounded-V_th)/Delta_T diff --git a/models/aeif_cond_exp.nestml b/models/aeif_cond_exp.nestml index bfccd8d9b..36cfcda22 100644 --- a/models/aeif_cond_exp.nestml +++ b/models/aeif_cond_exp.nestml @@ -41,7 +41,7 @@ neuron aeif_cond_exp_neuron: end equations: - V_bounded mV = min(V_m, V_peak) # prevent exponential divergence + V_bounded mV = bounded_min(V_m, V_peak) # prevent exponential divergence shape g_in = exp(-1/tau_syn_in*t) shape g_ex = exp(-1/tau_syn_ex*t) diff --git a/models/hh_cond_exp_traub.nestml b/models/hh_cond_exp_traub.nestml index 60379c323..c06841d58 100644 --- a/models/hh_cond_exp_traub.nestml +++ b/models/hh_cond_exp_traub.nestml @@ -36,7 +36,7 @@ neuron hh_cond_exp_traub_neuron: state: V_m mV = E_L # Membrane potential - # TODO: it should be possible, to define these variables in the internal block + # equilibrium values for (in)activation variables alias alpha_n_init real = 0.032 * ( 15. - V_m ) / ( exp( ( 15. - V_m ) / 5. ) - 1. ) alias beta_n_init real = 0.5 * exp( ( 10. - V_m ) / 40. ) alias alpha_m_init real = 0.32 * ( 13. - V_m ) / ( exp( ( 13. - V_m ) / 4. ) - 1. ) @@ -50,19 +50,22 @@ neuron hh_cond_exp_traub_neuron: end equations: + shape g_in = exp(-1/tau_syn_in*t) + shape g_ex = exp(-1/tau_syn_ex*t) + # Add aliases to simplify the equation definition of V_m + # ionic currents I_Na pA = g_Na * Act_m * Act_m * Act_m * Act_h * ( V_m - E_Na ) I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * ( V_m - E_K ) I_L pA = g_L * ( V_m - E_L ) + I_syn_exc pA = cond_sum(g_ex, spikeExc) * ( V_m - E_ex ) I_syn_inh pA = cond_sum(g_in, spikeInh) * ( V_m - E_in ) - shape g_in = exp(-1/tau_syn_in*t) - shape g_ex = exp(-1/tau_syn_ex*t) - + # membrane potential V_m' =( -I_Na - I_K - I_L - I_syn_exc - I_syn_inh + I_stim + I_e ) / C_m - # equilibrium values for (in)activation variables + # channel dynamics V_rel mV = V_m - V_T alpha_n real = 0.032 * ( 15. - V_rel ) / ( exp( ( 15. - V_rel ) / 5. ) - 1. ) beta_n real = 0.5 * exp( ( 10. - V_rel ) / 40. ) diff --git a/models/hh_psc_alpha.nestml b/models/hh_psc_alpha.nestml index 72d5e6b9f..88fa5a9e4 100644 --- a/models/hh_psc_alpha.nestml +++ b/models/hh_psc_alpha.nestml @@ -63,15 +63,15 @@ neuron hh_psc_alpha_neuron: equations: # synapses: alpha functions - shape I_in = 1 pA * (e/tau_syn_in) * t * exp(-1/tau_syn_in*t) - shape I_ex = 1 pA * (e/tau_syn_ex) * t * exp(-1/tau_syn_ex*t) + shape I_in = (e/tau_syn_in) * t * exp(-1/tau_syn_in*t) + shape I_ex = (e/tau_syn_ex) * t * exp(-1/tau_syn_ex*t) I_syn_exc pA = curr_sum(I_ex, spikeExc) I_syn_inh pA = curr_sum(I_in, spikeInh) I_Na pA = g_Na * Act_m * Act_m * Act_m * Act_h * ( V_m - E_Na ) I_K pA = g_K * Inact_n * Inact_n * Inact_n * Inact_n * ( V_m - E_K ) I_L pA = g_L * ( V_m - E_L ) - V_m' =( -( I_Na + I_K + I_L ) + I_stim + I_e + I_syn_inh + I_syn_exc ) / C_m + V_m' =( -( I_Na + I_K + I_L ) + currents + I_e + I_syn_inh + I_syn_exc ) / C_m # Inact_n alpha_n real = ( 0.01 * ( V_m + 55. ) ) / ( 1. - exp( -( V_m + 55. ) / 10. ) ) @@ -83,7 +83,7 @@ neuron hh_psc_alpha_neuron: beta_m real = 4. * exp( -( V_m + 65. ) / 18. ) Act_m' = alpha_m * ( 1 - Act_m ) - beta_m * Act_m # m-variable - # Act_h' + # Act_h alpha_h real = 0.07 * exp( -( V_m + 65. ) / 20. ) beta_h real = 1. / ( 1. + exp( -( V_m + 35. ) / 10. ) ) Act_h' = alpha_h * ( 1 - Act_h ) - beta_h * Act_h # h-variable @@ -115,11 +115,6 @@ neuron hh_psc_alpha_neuron: RefractoryCounts integer = steps(t_ref) # refractory time in steps r integer # number of steps in the current refractory phase - - # Input current injected by CurrentEvent. - # This variable is used to transport the current applied into the - # _dynamics function computing the derivative of the state vector. - I_stim pA = 0pA end input: @@ -136,12 +131,11 @@ neuron hh_psc_alpha_neuron: # sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum... if r > 0: # is refractory? r -= 1 - elif V_m > 0 and U_old > V_m: # threshold && maximum + elif V_m > 0mV and U_old > V_m: # threshold && maximum r = RefractoryCounts emit_spike() end - I_stim = currents.get_sum() end end diff --git a/models/iaf_cond_alpha_implicit.nestml b/models/iaf_cond_alpha_implicit.nestml index 08a823d42..153873561 100644 --- a/models/iaf_cond_alpha_implicit.nestml +++ b/models/iaf_cond_alpha_implicit.nestml @@ -48,8 +48,8 @@ neuron iaf_cond_alpha_implicit: g_ex'' = -g_ex'/tau_syn_ex g_ex' = g_ex' -g_ex/tau_syn_ex - I_syn_exc pA = cond_sum(g_ex, spikeExc) * ( V_m - E_ex ) - I_syn_inh pA = cond_sum(g_in, spikeInh) * ( V_m - E_in ) + I_syn_exc pA = cond_sum(g_ex, spikeExc) * ( V_m - E_ex ) + I_syn_inh pA = cond_sum(g_in, spikeInh) * ( V_m - E_in ) I_leak pA = g_L * ( V_m - E_L ) V_m' = ( -I_leak - I_syn_exc - I_syn_inh + I_stim + I_e ) / C_m @@ -106,8 +106,8 @@ neuron iaf_cond_alpha_implicit: end # add incoming spikes - g_ex' += spikeExc.get_sum() * PSConInit_E - g_in' += spikeInh.get_sum() * PSConInit_I + g_ex' += spikeExc * PSConInit_E + g_in' += spikeInh * PSConInit_I # set new input current I_stim = currents.get_sum() end diff --git a/src/main/java/org/nest/codegeneration/NestCodeGenerator.java b/src/main/java/org/nest/codegeneration/NestCodeGenerator.java index f9b7c23f9..46184f66b 100644 --- a/src/main/java/org/nest/codegeneration/NestCodeGenerator.java +++ b/src/main/java/org/nest/codegeneration/NestCodeGenerator.java @@ -5,13 +5,17 @@ */ package org.nest.codegeneration; +import com.google.common.collect.Lists; +import com.google.common.io.Files; import de.monticore.generating.GeneratorEngine; import de.monticore.generating.GeneratorSetup; import de.monticore.generating.templateengine.GlobalExtensionManagement; +import de.se_rwth.commons.logging.Log; import org.nest.codegeneration.converters.*; import org.nest.codegeneration.helpers.*; import org.nest.codegeneration.sympy.ODETransformer; import org.nest.codegeneration.sympy.OdeProcessor; +import org.nest.codegeneration.sympy.TransformerBase; import org.nest.nestml._ast.ASTBody; import org.nest.nestml._ast.ASTNESTMLCompilationUnit; import org.nest.nestml._ast.ASTNeuron; @@ -23,8 +27,11 @@ import org.nest.utils.AstUtils; import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.List; import java.util.Optional; @@ -84,6 +91,7 @@ private ASTNeuron solveODESInNeuron( if (odesBlock.isPresent()) { if (odesBlock.get().getShapes().size() == 0) { info("The model will be solved numerically with GSL solver.", LOG_NAME); + markNumericSolver(astNeuron.getName(), outputBase); return astNeuron; } else { @@ -98,6 +106,17 @@ private ASTNeuron solveODESInNeuron( } + private void markNumericSolver(final String neuronName, final Path outputBase) { + try { + Files.write("numeric", + Paths.get(outputBase.toString(), neuronName + "." + TransformerBase.SOLVER_TYPE).toFile(), + Charset.defaultCharset()); + } + catch (IOException e) { + Log.error("Cannot write status file. Check you permissions.", e); + } + } + private void generateNestCode( final ASTNeuron astNeuron, final Path outputBase) { diff --git a/src/main/java/org/nest/codegeneration/SolverType.java b/src/main/java/org/nest/codegeneration/SolverType.java index e9cd5cdb2..fa04ff553 100644 --- a/src/main/java/org/nest/codegeneration/SolverType.java +++ b/src/main/java/org/nest/codegeneration/SolverType.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/org/nest/codegeneration/converters/GslReferenceConverter.java b/src/main/java/org/nest/codegeneration/converters/GslReferenceConverter.java index 528aa41ef..f1f0a6a48 100644 --- a/src/main/java/org/nest/codegeneration/converters/GslReferenceConverter.java +++ b/src/main/java/org/nest/codegeneration/converters/GslReferenceConverter.java @@ -81,10 +81,10 @@ public String convertFunctionCall(final ASTFunctionCall astFunctionCall) { if (PredefinedFunctions.POW.equals(functionName)) { return "pow(%s)"; } - if (PredefinedFunctions.MAX.equals(functionName)) { + if (PredefinedFunctions.MAX.equals(functionName) || PredefinedFunctions.BOUNDED_MAX.equals(functionName)) { return "std::max(%s)"; } - if (PredefinedFunctions.MIN.equals(functionName)) { + if (PredefinedFunctions.MIN.equals(functionName)|| PredefinedFunctions.BOUNDED_MIN.equals(functionName)) { return "std::min(%s)"; } if (functionName.contains(PredefinedFunctions.EMIT_SPIKE)) { diff --git a/src/main/java/org/nest/codegeneration/converters/NESTReferenceConverter.java b/src/main/java/org/nest/codegeneration/converters/NESTReferenceConverter.java index 4a3ff7691..2edf04504 100644 --- a/src/main/java/org/nest/codegeneration/converters/NESTReferenceConverter.java +++ b/src/main/java/org/nest/codegeneration/converters/NESTReferenceConverter.java @@ -72,10 +72,10 @@ public String convertFunctionCall(final ASTFunctionCall astFunctionCall) { if (PredefinedFunctions.POW.equals(functionName)) { return "std::pow(%s)"; } - if (PredefinedFunctions.MAX.equals(functionName)) { + if (PredefinedFunctions.MAX.equals(functionName) || PredefinedFunctions.BOUNDED_MAX.equals(functionName)) { return "std::max(%s)"; } - if (PredefinedFunctions.MIN.equals(functionName)) { + if (PredefinedFunctions.MIN.equals(functionName) || PredefinedFunctions.BOUNDED_MIN.equals(functionName) ) { return "std::min(%s)"; } diff --git a/src/main/java/org/nest/codegeneration/sympy/DeltaSolutionTransformer.java b/src/main/java/org/nest/codegeneration/sympy/DeltaSolutionTransformer.java index 4d869d600..08abc207d 100644 --- a/src/main/java/org/nest/codegeneration/sympy/DeltaSolutionTransformer.java +++ b/src/main/java/org/nest/codegeneration/sympy/DeltaSolutionTransformer.java @@ -32,7 +32,6 @@ */ class DeltaSolutionTransformer extends TransformerBase { final static String PROPAGATOR_STEP = "propagator.step.tmp"; - final static String ODE_TYPE = "solverType.tmp"; final static String P30_FILE = "P30.tmp"; ASTNeuron addExactSolution( diff --git a/src/main/java/org/nest/codegeneration/sympy/NESTMLASTCreator.java b/src/main/java/org/nest/codegeneration/sympy/NESTMLASTCreator.java index a9a86aa2c..73f36d249 100644 --- a/src/main/java/org/nest/codegeneration/sympy/NESTMLASTCreator.java +++ b/src/main/java/org/nest/codegeneration/sympy/NESTMLASTCreator.java @@ -38,7 +38,7 @@ public class NESTMLASTCreator { } static List createAliases(final Path declarationFile) { - checkArgument(Files.exists(declarationFile)); + checkArgument(Files.exists(declarationFile), declarationFile.toString()); try { return Files.lines(declarationFile) diff --git a/src/main/java/org/nest/codegeneration/sympy/ODESolverGenerator.java b/src/main/java/org/nest/codegeneration/sympy/ODESolverGenerator.java index 1e1bd40a0..8991243ca 100644 --- a/src/main/java/org/nest/codegeneration/sympy/ODESolverGenerator.java +++ b/src/main/java/org/nest/codegeneration/sympy/ODESolverGenerator.java @@ -161,6 +161,7 @@ private static Path generateSympyScript( glex.setGlobalValue("variables", variables); glex.setGlobalValue("aliases", aliases); + glex.setGlobalValue("neuronName", neuron.getName()); final ExpressionsPrettyPrinter expressionsPrinter = new ExpressionsPrettyPrinter(); glex.setGlobalValue("printer", expressionsPrinter); diff --git a/src/main/java/org/nest/codegeneration/sympy/ODETransformer.java b/src/main/java/org/nest/codegeneration/sympy/ODETransformer.java index 4abf86789..c308e5def 100644 --- a/src/main/java/org/nest/codegeneration/sympy/ODETransformer.java +++ b/src/main/java/org/nest/codegeneration/sympy/ODETransformer.java @@ -1,6 +1,7 @@ package org.nest.codegeneration.sympy; import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import de.monticore.ast.ASTNode; import org.nest.commons._ast.ASTExpr; import org.nest.commons._ast.ASTFunctionCall; @@ -19,23 +20,49 @@ * @author plotnikov */ public class ODETransformer { + private static final List functions = Lists.newArrayList( + PredefinedFunctions.CURR_SUM, + PredefinedFunctions.COND_SUM, + PredefinedFunctions.BOUNDED_MIN, + PredefinedFunctions.BOUNDED_MAX); + + private static final List sumFunctions = Lists.newArrayList( + PredefinedFunctions.CURR_SUM, + PredefinedFunctions.COND_SUM); + + + // this function is used in freemarker templates und must be public + public static T replaceFunctions(final T astOde) { + // since the transformation replaces the call inplace, make a copy to preserve the information for further steps + final List functionsCalls = getFunctionCalls(astOde, functions); + + final T workingCopy = (T) astOde.deepClone(); // IT is OK, since the deepClone returns T + functionsCalls.forEach(functionCall -> replaceFunctionCallThroughFirstArgument(astOde, functionCall)); // TODO deepClone + return astOde; + } + // this function is used in freemarker templates und must be public public static T replaceSumCalls(final T astOde) { // since the transformation replaces the call inplace, make a copy to preserve the information for further steps - final List functions = get_sumFunctionCalls(astOde); + final List functionsCalls = get_sumFunctionCalls(astOde); final T workingCopy = (T) astOde.deepClone(); // IT is OK, since the deepClone returns T - functions.forEach(node -> replaceFunctionCallThroughFirstArgument(astOde, node)); // TODO deepClone + functionsCalls.forEach(functionCall -> replaceFunctionCallThroughFirstArgument(astOde, functionCall)); // TODO deepClone return astOde; } + + // this function is used in freemarker templates und must be public static List get_sumFunctionCalls(final ASTNode workingCopy) { + return getFunctionCalls(workingCopy, sumFunctions); + } + + // this function is used in freemarker templates und must be public + private static List getFunctionCalls(final ASTNode workingCopy, final List functionNames) { return AstUtils.getAll(workingCopy, ASTFunctionCall.class) .stream() - .filter(astFunctionCall -> - astFunctionCall.getCalleeName().equals(PredefinedFunctions.CURR_SUM) || - astFunctionCall.getCalleeName().equals(PredefinedFunctions.COND_SUM)) + .filter(astFunctionCall -> functionNames.contains(astFunctionCall.getCalleeName())) .collect(Collectors.toList()); } diff --git a/src/main/java/org/nest/codegeneration/sympy/OdeProcessor.java b/src/main/java/org/nest/codegeneration/sympy/OdeProcessor.java index 16f09c31f..469bf4590 100644 --- a/src/main/java/org/nest/codegeneration/sympy/OdeProcessor.java +++ b/src/main/java/org/nest/codegeneration/sympy/OdeProcessor.java @@ -100,7 +100,7 @@ private ASTNeuron handleDeltaShape( checkState(successfulExecution, "Error during solver script evaluation."); - final Path odeTypePath = Paths.get(outputBase.toString(), DeltaSolutionTransformer.ODE_TYPE); + final Path odeTypePath = Paths.get(outputBase.toString(), astNeuron.getName() + "." + DeltaSolutionTransformer.SOLVER_TYPE); final SolverType solutionType = SolverType.fromFile(odeTypePath); if (solutionType.equals(SolverType.EXACT)) { @@ -109,8 +109,8 @@ private ASTNeuron handleDeltaShape( LOG_NAME); deltaSolutionTransformer.addExactSolution( astNeuron, - Paths.get(outputBase.toString(), DeltaSolutionTransformer.P30_FILE), - Paths.get(outputBase.toString(), DeltaSolutionTransformer.PROPAGATOR_STEP)); + Paths.get(outputBase.toString(), astNeuron.getName() + "." + DeltaSolutionTransformer.P30_FILE), + Paths.get(outputBase.toString(), astNeuron.getName() + "." + DeltaSolutionTransformer.PROPAGATOR_STEP)); } else { Log.warn(astNeuron.getName() + " has a delta shape function with a non-linear ODE."); @@ -137,7 +137,7 @@ protected ASTNeuron handleNeuronWithODE( checkState(successfulExecution, "Error during solver script evaluation."); - final Path odeTypePath = Paths.get(outputBase.toString(), TransformerBase.SOLVER_TYPE); + final Path odeTypePath = Paths.get(outputBase.toString(), astNeuron.getName() + "." + TransformerBase.SOLVER_TYPE); final SolverType solutionType = SolverType.fromFile(odeTypePath); if (solutionType.equals(SolverType.EXACT)) { @@ -145,21 +145,21 @@ protected ASTNeuron handleNeuronWithODE( return linearSolutionTransformer.addExactSolution( astNeuron, - Paths.get(outputBase.toString(), LinearSolutionTransformer.P30_FILE), - Paths.get(outputBase.toString(), LinearSolutionTransformer.PSC_INITIAL_VALUE_FILE), - Paths.get(outputBase.toString(), LinearSolutionTransformer.STATE_VARIABLES_FILE), - Paths.get(outputBase.toString(), LinearSolutionTransformer.PROPAGATOR_MATRIX_FILE), - Paths.get(outputBase.toString(), LinearSolutionTransformer.PROPAGATOR_STEP_FILE), - Paths.get(outputBase.toString(), LinearSolutionTransformer.STATE_VECTOR_TMP_DECLARATIONS_FILE), - Paths.get(outputBase.toString(), LinearSolutionTransformer.STATE_VECTOR_UPDATE_STEPS_FILE), - Paths.get(outputBase.toString(), LinearSolutionTransformer.STATE_VECTOR_TMP_BACK_ASSIGNMENTS_FILE)); + Paths.get(outputBase.toString(), astNeuron.getName() + "." + LinearSolutionTransformer.P30_FILE), + Paths.get(outputBase.toString(), astNeuron.getName() + "." + LinearSolutionTransformer.PSC_INITIAL_VALUE_FILE), + Paths.get(outputBase.toString(), astNeuron.getName() + "." + LinearSolutionTransformer.STATE_VARIABLES_FILE), + Paths.get(outputBase.toString(), astNeuron.getName() + "." + LinearSolutionTransformer.PROPAGATOR_MATRIX_FILE), + Paths.get(outputBase.toString(), astNeuron.getName() + "." + LinearSolutionTransformer.PROPAGATOR_STEP_FILE), + Paths.get(outputBase.toString(), astNeuron.getName() + "." + LinearSolutionTransformer.STATE_VECTOR_TMP_DECLARATIONS_FILE), + Paths.get(outputBase.toString(), astNeuron.getName() + "." + LinearSolutionTransformer.STATE_VECTOR_UPDATE_STEPS_FILE), + Paths.get(outputBase.toString(), astNeuron.getName() + "." + LinearSolutionTransformer.STATE_VECTOR_TMP_BACK_ASSIGNMENTS_FILE)); } else if (solutionType.equals(SolverType.NUMERIC)) { info("ODE is solved numerically.", LOG_NAME); return implicitFormTransformer.transformToImplicitForm( astNeuron, - Paths.get(outputBase.toString(),ImplicitFormTransformer.PSC_INITIAL_VALUE_FILE), - Paths.get(outputBase.toString(),ImplicitFormTransformer.EQUATIONS_FILE)); + Paths.get(outputBase.toString(), astNeuron.getName() + "." + ImplicitFormTransformer.PSC_INITIAL_VALUE_FILE), + Paths.get(outputBase.toString(),astNeuron.getName() + "." + ImplicitFormTransformer.EQUATIONS_FILE)); } else { warn(astNeuron.getName() + ": ODEs could not be solved. The model remains unchanged."); diff --git a/src/main/java/org/nest/frontend/CliConfigurationExecutor.java b/src/main/java/org/nest/frontend/CliConfigurationExecutor.java index 46a39e63f..195c8614e 100644 --- a/src/main/java/org/nest/frontend/CliConfigurationExecutor.java +++ b/src/main/java/org/nest/frontend/CliConfigurationExecutor.java @@ -11,7 +11,9 @@ import de.se_rwth.commons.logging.Log; import org.apache.commons.io.FilenameUtils; import org.nest.codegeneration.NestCodeGenerator; +import org.nest.codegeneration.sympy.TransformerBase; import org.nest.nestml._ast.ASTNESTMLCompilationUnit; +import org.nest.nestml._ast.ASTNeuron; import org.nest.nestml._parser.NESTMLParser; import org.nest.nestml._symboltable.NESTMLScopeCreator; import org.nest.nestml._symboltable.NestmlCoCosManager; @@ -24,6 +26,7 @@ import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.*; import static java.util.stream.Collectors.joining; @@ -178,8 +181,24 @@ private void generateNeuronCode(List modelRoots, CliCo for (final ASTNESTMLCompilationUnit root:modelRoots) { reporter.reportProgress("Generate NEST code from the artifact: " + root.getFullName() + "..."); generator.analyseAndGenerate(root, config.getTargetPath()); - final String msg = "NEST code for the artifact: " + root.getFullName() + " is generated."; - reporter.addArtifactInfo(root.getArtifactName(), msg, Reporter.Level.INFO); + checkGeneratedCode(root, config.getTargetPath()); + } + + } + + private void checkGeneratedCode(final ASTNESTMLCompilationUnit root, final Path targetPath) { + for (final ASTNeuron astNeuron:root.getNeurons()) { + if (Files.exists(Paths.get(targetPath.toString(), astNeuron.getName() + "." + TransformerBase.SOLVER_TYPE))) { + + final String msg = "NEST code for the neuron: " + astNeuron.getName() + " in " + root.getFullName() + + " was generated."; + reporter.addArtifactInfo(root.getArtifactName(), msg, Reporter.Level.INFO); + } else { + + final String msg = "NEST code for the neuron: " + astNeuron.getName() + " in " + root.getFullName() + + " wasn't generated."; + reporter.addArtifactInfo(root.getArtifactName(), msg, Reporter.Level.ERROR); + } } } @@ -196,7 +215,7 @@ private boolean checkModels(List modelRoots, CliConfig final List modelFindings = checker.analyzeModel(root); findingsToModel.put(root.getArtifactName(), modelFindings); - if (findingsToModel.get(root.getArtifactName()).stream().filter(Finding::isError).findAny().isPresent()) { + if (findingsToModel.get(root.getArtifactName()).stream().anyMatch(Finding::isError)) { anyError = true; } reporter.addArtifactFindings(root.getArtifactName(), modelFindings); diff --git a/src/main/java/org/nest/symboltable/predefined/PredefinedFunctions.java b/src/main/java/org/nest/symboltable/predefined/PredefinedFunctions.java index 0668a8f41..69445c06d 100644 --- a/src/main/java/org/nest/symboltable/predefined/PredefinedFunctions.java +++ b/src/main/java/org/nest/symboltable/predefined/PredefinedFunctions.java @@ -38,7 +38,9 @@ public class PredefinedFunctions { private static final String EXPM1 = "expm1"; public static final String DELTA = "delta"; public static final String MAX = "max"; + public static final String BOUNDED_MAX = "bounded_max"; public static final String MIN = "min"; + public static final String BOUNDED_MIN = "bounded_min"; public static final String INTEGRATE_ODES = "integrate_odes"; public static final String CURR_SUM = "curr_sum"; public static final String COND_SUM = "cond_sum"; @@ -121,12 +123,24 @@ public class PredefinedFunctions { max.setReturnType(getType("real")); name2FunctionSymbol.put(MAX, max); + final MethodSymbol boundedMax = createFunctionSymbol(BOUNDED_MAX); + boundedMax.addParameterType(getType("real")); + boundedMax.addParameterType(getType("real")); + boundedMax.setReturnType(getType("real")); + name2FunctionSymbol.put(BOUNDED_MAX, boundedMax); + final MethodSymbol min = createFunctionSymbol(MIN); min.addParameterType(getType("real")); min.addParameterType(getType("real")); min.setReturnType(getType("real")); name2FunctionSymbol.put(MIN, min); + final MethodSymbol boundedMin = createFunctionSymbol(BOUNDED_MIN); + boundedMin.addParameterType(getType("real")); + boundedMin.addParameterType(getType("real")); + boundedMin.setReturnType(getType("real")); + name2FunctionSymbol.put(BOUNDED_MIN, boundedMin); + final MethodSymbol integrate = createFunctionSymbol(INTEGRATE_ODES); integrate.setReturnType(getVoidType()); name2FunctionSymbol.put(INTEGRATE_ODES, integrate); diff --git a/src/main/resources/org/nest/sympy/DeltaShapeSolver.ftl b/src/main/resources/org/nest/sympy/DeltaShapeSolver.ftl index fb1f75b3f..5682d1a82 100644 --- a/src/main/resources/org/nest/sympy/DeltaShapeSolver.ftl +++ b/src/main/resources/org/nest/sympy/DeltaShapeSolver.ftl @@ -30,15 +30,15 @@ dev${ode.getLhs().getSimpleName()} = diff(rhs, ${ode.getLhs().getSimpleName()}) dev_t_dev${ode.getLhs().getSimpleName()} = diff(dev${ode.getLhs().getSimpleName()}, t) if dev_t_dev${ode.getLhs().getSimpleName()} == 0: - solverType = open('solverType.tmp', 'w') + solverType = open('${neuronName}.solverType.tmp', 'w') solverType.write("exact") - propagatorStepFile = open('propagator.step.tmp', 'w') + propagatorStepFile = open('${neuronName}.propagator.step.tmp', 'w') propagatorStepFile.write("${ode.getLhs().getSimpleName()} += P30 * (" + str(constantInputs) + ") ") # calculate -1/Tau c1 = diff(rhs, ${ode.getLhs().getSimpleName()}) # The symbol must be declared again. Otherwise, the right hand side will be used for the derivative ${shapes[0].getLhs()} = symbols("${shapes[0].getLhs()}") c2 = diff( ${printer.print(odeTransformer.replaceSumCalls(ode.getRhs()))} , ${shapes[0].getLhs()}) - f = open('P30.tmp', 'w') + f = open('${neuronName}.P30.tmp', 'w') f.write("P30 real = " + str(simplify(c2 / c1 * (exp(__h__ * c1) - 1))) + "# P00 expression") \ No newline at end of file diff --git a/src/main/resources/org/nest/sympy/ODESolver.ftl b/src/main/resources/org/nest/sympy/ODESolver.ftl index 45d8f35e7..49da10a1f 100644 --- a/src/main/resources/org/nest/sympy/ODESolver.ftl +++ b/src/main/resources/org/nest/sympy/ODESolver.ftl @@ -8,9 +8,9 @@ __a__, __h__ = symbols('__a__ __h__') # Shapes must be symbolic for the differetiation step. Also all aliases which are using shapes must be defined with symbolic shapes <#list aliases as alias> -${alias.getName()} = ${printer.print(odeTransformer.replaceSumCalls(alias.getDeclaringExpression().get()))} +${alias.getName()} = ${printer.print(odeTransformer.replaceFunctions(alias.getDeclaringExpression().get()))} -rhsTmp = ${printer.print(odeTransformer.replaceSumCalls(ode.getRhs()))} +rhsTmp = ${printer.print(odeTransformer.replaceFunctions(ode.getRhs()))} constantInputs = simplify(1/diff(rhsTmp, ${shapes[0].getLhs()}) * (rhsTmp - diff(rhsTmp, ${ode.getLhs().getSimpleName()})*${ode.getLhs().getSimpleName()}) - ( <#assign operator = ""> <#compress> <#list shapes as eq> @@ -21,14 +21,14 @@ ${operator} ${eq.getLhs()} # print the definition of the shape <#list shapes as eq> -${eq.getLhs()} = ${printer.print(odeTransformer.replaceSumCalls(eq.getRhs()))} +${eq.getLhs()} = ${printer.print(odeTransformer.replaceFunctions(eq.getRhs()))} # also aliases must be defined in terms of new shapes <#list aliases as alias> -${alias.getName()} = ${printer.print(odeTransformer.replaceSumCalls(alias.getDeclaringExpression().get()))} +${alias.getName()} = ${printer.print(odeTransformer.replaceFunctions(alias.getDeclaringExpression().get()))} -rhs = ${printer.print(odeTransformer.replaceSumCalls(ode.getRhs()))} +rhs = ${printer.print(odeTransformer.replaceFunctions(ode.getRhs()))} dev${ode.getLhs().getSimpleName()} = diff(rhs, ${ode.getLhs().getSimpleName()}) dev_t_dev${ode.getLhs().getSimpleName()} = diff(dev${ode.getLhs().getSimpleName()}, t) @@ -102,7 +102,7 @@ if dev_t_dev${ode.getLhs().getSimpleName()} == 0: c1 = diff(rhs, ${ode.getLhs().getSimpleName()}) # The symbol must be declared again. Otherwise, the right hand side will be used for the derivative ${shapes[0].getLhs()} = symbols("${shapes[0].getLhs()}") - c2 = diff( ${printer.print(odeTransformer.replaceSumCalls(ode.getRhs()))} , ${shapes[0].getLhs()}) + c2 = diff( ${printer.print(odeTransformer.replaceFunctions(ode.getRhs()))} , ${shapes[0].getLhs()}) # define matrices depending on order # for order 1 and 2 A is lower triangular matrix @@ -133,11 +133,11 @@ if dev_t_dev${ode.getLhs().getSimpleName()} == 0: shapes = [<#compress> <#list shapes as eq> "${eq.getLhs()}", ] - stateVariablesFile = open('state.variables.tmp', 'w') - initialValueFile = open('pscInitialValues.tmp', 'w') - stateVectorTmpDeclarationsFile = open('state.vector.tmp.declarations.tmp', 'w') - stateVectorUpdateSteps = open('state.vector.update.steps.tmp', 'w') - stateVectorTmpBackAssignmentsFile = open('state.vector.tmp.back.assignments.tmp', 'w') + stateVariablesFile = open('${neuronName}.state.variables.tmp', 'w') + initialValueFile = open('${neuronName}.pscInitialValues.tmp', 'w') + stateVectorTmpDeclarationsFile = open('${neuronName}.state.vector.tmp.declarations.tmp', 'w') + stateVectorUpdateSteps = open('${neuronName}.state.vector.update.steps.tmp', 'w') + stateVectorTmpBackAssignmentsFile = open('${neuronName}.state.vector.tmp.back.assignments.tmp', 'w') stateVectors = zeros(max(orders) + 1, len(shapes)) for shapeIndex in range(0, len(shapes)): @@ -171,10 +171,10 @@ if dev_t_dev${ode.getLhs().getSimpleName()} == 0: stateVectorTmpBackAssignmentsFile.write(stateVariables[i] + shapes[shapeIndex] + " = " + stateVariables[i] + shapes[shapeIndex] + "_tmp" + "\n") - f = open('P30.tmp', 'w') + f = open('${neuronName}.P30.tmp', 'w') f.write("P30 real = " + str(simplify(c2 / c1 * (exp(__h__ * c1) - 1))) + "# P00 expression") - propagatorMatrixFile = open('propagator.matrix.tmp', 'w') + propagatorMatrixFile = open('${neuronName}.propagator.matrix.tmp', 'w') tmpPropagator = [None]*len(shapes) for shapeIndex in range(0, len(shapes)): tmpPropagator[shapeIndex] = zeros(len(Ps[0].row(0)), len(Ps[0].col(0))) @@ -184,7 +184,7 @@ if dev_t_dev${ode.getLhs().getSimpleName()} == 0: "P_" + shapes[shapeIndex] + "_" + str(rowIndex) + str(colIndex) + " real = " + str(Ps[shapeIndex][rowIndex, colIndex]) + "\n") tmpPropagator[shapeIndex][rowIndex, colIndex] = symbols("P_" + shapes[shapeIndex] + "_" + str(rowIndex) + str(colIndex)); - updateStep = open('propagator.step.tmp', 'w') + updateStep = open('${neuronName}.propagator.step.tmp', 'w') # the multiplication only once. It is computation related to lefthandside of the ode. tmp = Ps[0][orders[shapeIndex], orders[shapeIndex]] * stateVectors.col(shapeIndex)[orders[shapeIndex]] @@ -195,7 +195,7 @@ if dev_t_dev${ode.getLhs().getSimpleName()} == 0: 0:(orders[shapeIndex])] * stateVectors.col(shapeIndex)[0:orders[shapeIndex], 0])[orders[shapeIndex] - 1]) + "\n") - solverType = open('solverType.tmp', 'w') + solverType = open('${neuronName}.solverType.tmp', 'w') solverType.write("exact") print('Successfully solved the ODE with shapes ' + str(shapes) + ' exactly.') else: @@ -270,8 +270,8 @@ else: prefixes = ["", "__D", "__D__D", "__D__D__D"] def transform(expression): return expression.replace("__D", "\'") - initialValuesFile = open('pscInitialValues.tmp', 'w') - implicitFormFile = open('equations.tmp', 'w') + initialValuesFile = open('${neuronName}.pscInitialValues.tmp', 'w') + implicitFormFile = open('${neuronName}.equations.tmp', 'w') for shape_index in range(0, len(shapes)): odeOrder = orders[shape_index] shape = shapes[shape_index] @@ -293,6 +293,6 @@ else: implicitFormFile.write(transform(str(derivatives[odeOrder]) + " = " + str(simplify(rhs)) + "\n")) for order in range(1, odeOrder): implicitFormFile.write(transform(str(derivatives[order]) + " = " + transform(str(derivatives[order])) + "\n")) - solverType = open('solverType.tmp', 'w') + solverType = open('${neuronName}.solverType.tmp', 'w') solverType.write("numeric") print('Successfully converted shapes ' + str(shapes) + ' into the implicit from.') \ No newline at end of file diff --git a/src/test/java/org/nest/codegeneration/SolverTypeTest.java b/src/test/java/org/nest/codegeneration/SolverTypeTest.java index 58859024c..44b62dbb9 100644 --- a/src/test/java/org/nest/codegeneration/SolverTypeTest.java +++ b/src/test/java/org/nest/codegeneration/SolverTypeTest.java @@ -17,7 +17,7 @@ * @author plotnikov */ public class SolverTypeTest { - private final static String SOLVER_TYPE_FILE = "src/test/resources/codegeneration/sympy/psc/solverType.tmp"; + private final static String SOLVER_TYPE_FILE = "src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.solverType.tmp"; @Test public void testLoadTypeFromFile() { diff --git a/src/test/java/org/nest/codegeneration/sympy/DeltaSolutionTransformerTest.java b/src/test/java/org/nest/codegeneration/sympy/DeltaSolutionTransformerTest.java index 4d1e70617..6ee838c22 100644 --- a/src/test/java/org/nest/codegeneration/sympy/DeltaSolutionTransformerTest.java +++ b/src/test/java/org/nest/codegeneration/sympy/DeltaSolutionTransformerTest.java @@ -25,16 +25,17 @@ */ public class DeltaSolutionTransformerTest extends ModelbasedTest { private static final String TARGET_TMP_MODEL_PATH = "target/tmp.nestml"; + private static final String NEURON_NAME = "iaf_psc_delta_neuron"; + private static final String MODEL_FILE_PATH = "models/iaf_psc_delta.nestml"; private final static Path P30_FILE = Paths.get( - "src/test/resources/codegeneration/sympy/psc/", - DeltaSolutionTransformer.P30_FILE); + "src/test/resources/codegeneration/sympy/delta/", + NEURON_NAME + "." + DeltaSolutionTransformer.P30_FILE); private final static Path PROPAGATPR_STEP_FILE = Paths.get( - "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.PROPAGATOR_STEP_FILE); - private static final String NEURON_NAME = "iaf_psc_delta_neuron"; - private static final String MODEL_FILE_PATH = "models/iaf_psc_delta.nestml"; + "src/test/resources/codegeneration/sympy/delta/", + NEURON_NAME + "." + LinearSolutionTransformer.PROPAGATOR_STEP_FILE); + @Test public void testAddingSolution() { @@ -43,7 +44,8 @@ public void testAddingSolution() { final DeltaSolutionTransformer deltaSolutionTransformer = new DeltaSolutionTransformer(); - deltaSolutionTransformer.addExactSolution(modelRoot.getNeurons().get(0), P30_FILE, PROPAGATPR_STEP_FILE); + deltaSolutionTransformer.addExactSolution( + modelRoot.getNeurons().get(0), P30_FILE, PROPAGATPR_STEP_FILE); printModelToFile(modelRoot, TARGET_TMP_MODEL_PATH); diff --git a/src/test/java/org/nest/codegeneration/sympy/ExpressionFolderTest.java b/src/test/java/org/nest/codegeneration/sympy/ExpressionFolderTest.java index ac5a673df..6aa3a1789 100644 --- a/src/test/java/org/nest/codegeneration/sympy/ExpressionFolderTest.java +++ b/src/test/java/org/nest/codegeneration/sympy/ExpressionFolderTest.java @@ -32,14 +32,14 @@ */ public class ExpressionFolderTest extends ModelbasedTest { private static final ExpressionsPrettyPrinter printer = new ExpressionsPrettyPrinter(); - + private static final String NEURON_NAME = "iaf_psc_alpha_neuron"; private static final String MODEL_FILE_PATH = "models/iaf_psc_alpha.nestml"; private final static Path STATE_VARIABLES_FILE = Paths.get( "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.STATE_VARIABLES_FILE); + NEURON_NAME + "." + LinearSolutionTransformer.STATE_VARIABLES_FILE); private final static Path STATE_UPDATE_STEPS_FILE = Paths.get( "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.STATE_VECTOR_UPDATE_STEPS_FILE); + NEURON_NAME + "." + LinearSolutionTransformer.STATE_VECTOR_UPDATE_STEPS_FILE); @Test public void testExpressionFolding() throws IOException { diff --git a/src/test/java/org/nest/codegeneration/sympy/LinearSolutionTransformerTest.java b/src/test/java/org/nest/codegeneration/sympy/LinearSolutionTransformerTest.java index 78b8546e6..0aa97f751 100644 --- a/src/test/java/org/nest/codegeneration/sympy/LinearSolutionTransformerTest.java +++ b/src/test/java/org/nest/codegeneration/sympy/LinearSolutionTransformerTest.java @@ -26,43 +26,42 @@ * @author plonikov */ public class LinearSolutionTransformerTest extends ModelbasedTest { - + private static final String NEURON_NAME = "iaf_psc_alpha_neuron"; + private static final String MODEL_FILE_PATH = "models/iaf_psc_alpha.nestml"; private static final String TARGET_TMP_MODEL_PATH = "target/tmp.nestml"; private final static Path P30_FILE = Paths.get( "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.P30_FILE); + NEURON_NAME + "." + LinearSolutionTransformer.P30_FILE); private final static Path PSC_INITIAL_VALUE_FILE = Paths.get( "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.PSC_INITIAL_VALUE_FILE); + NEURON_NAME + "." + LinearSolutionTransformer.PSC_INITIAL_VALUE_FILE); private final static Path STATE_VARIABLES_FILE = Paths.get( "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.STATE_VARIABLES_FILE); + NEURON_NAME + "." + LinearSolutionTransformer.STATE_VARIABLES_FILE); private final static Path PROPAGATPR_MATRIX_FILE = Paths.get( "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.PROPAGATOR_MATRIX_FILE); + NEURON_NAME + "." + LinearSolutionTransformer.PROPAGATOR_MATRIX_FILE); private final static Path PROPAGATPR_STEP_FILE = Paths.get( "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.PROPAGATOR_STEP_FILE); + NEURON_NAME + "." + LinearSolutionTransformer.PROPAGATOR_STEP_FILE); private final static Path STATE_VECTOR_TMP_DECLARATIONS_FILE = Paths.get( "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.STATE_VECTOR_TMP_DECLARATIONS_FILE); + NEURON_NAME + "." + LinearSolutionTransformer.STATE_VECTOR_TMP_DECLARATIONS_FILE); private final static Path STATE_UPDATE_STEPS_FILE = Paths.get( "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.STATE_VECTOR_UPDATE_STEPS_FILE); + NEURON_NAME + "." + LinearSolutionTransformer.STATE_VECTOR_UPDATE_STEPS_FILE); private final static Path STATE_VECTOR_BACK_ASSIGNMENTS_FILE = Paths.get( "src/test/resources/codegeneration/sympy/psc/", - LinearSolutionTransformer.STATE_VECTOR_TMP_BACK_ASSIGNMENTS_FILE); + NEURON_NAME + "." + LinearSolutionTransformer.STATE_VECTOR_TMP_BACK_ASSIGNMENTS_FILE); - private static final String NEURON_NAME = "iaf_psc_alpha_neuron"; - private static final String MODEL_FILE_PATH = "models/iaf_psc_alpha.nestml"; @Test public void testExactSolutionTransformation() { diff --git a/src/test/java/org/nest/codegeneration/sympy/NESTMLASTCreatorTest.java b/src/test/java/org/nest/codegeneration/sympy/NESTMLASTCreatorTest.java index 96536f494..c7e73aac3 100644 --- a/src/test/java/org/nest/codegeneration/sympy/NESTMLASTCreatorTest.java +++ b/src/test/java/org/nest/codegeneration/sympy/NESTMLASTCreatorTest.java @@ -23,13 +23,11 @@ public class NESTMLASTCreatorTest { private static final String P_30 = "P30"; - private final static String P30_FILE = "src/test/resources/codegeneration/sympy/psc/P30.tmp"; - - private final NESTMLASTCreator converter = new NESTMLASTCreator(); + private final static String P30_FILE = "src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.P30.tmp"; @Test public void testConvertToDeclaration() throws Exception { - final ASTAliasDecl testant = converter.createAliases(Paths.get(P30_FILE)).get(0); + final ASTAliasDecl testant = NESTMLASTCreator.createAliases(Paths.get(P30_FILE)).get(0); assertEquals(testant.getDeclaration().getVars().get(0), P_30); assertTrue(testant.getDeclaration().getExpr().isPresent()); @@ -40,7 +38,7 @@ public void testConvertString2Alias() { final String testExpr = "P30 real = -Tau*tau_in*(Tau*h*exp(h/Tau) + Tau*tau_in*exp(h/Tau) - Tau*tau_in*exp" + "(h/tau_in) - " + "h*tau_in*exp(h/Tau))*exp(-h/tau_in - h/Tau)/(C*(Tau**2 - 2*Tau*tau_in + tau_in**2)) # PXX"; - final ASTAliasDecl testant = converter.createAlias(testExpr); + final ASTAliasDecl testant = NESTMLASTCreator.createAlias(testExpr); assertNotNull(testant); assertEquals(1, testant.getDeclaration().getVars().size()); assertEquals(P_30, testant.getDeclaration().getVars().get(0)); diff --git a/src/test/java/org/nest/integration/NestmlFrontendIntegrationTest.java b/src/test/java/org/nest/integration/NestmlFrontendIntegrationTest.java index 74b6e667a..42fea0aae 100644 --- a/src/test/java/org/nest/integration/NestmlFrontendIntegrationTest.java +++ b/src/test/java/org/nest/integration/NestmlFrontendIntegrationTest.java @@ -67,7 +67,7 @@ public void testTutorialModels() { @Test public void manually() { final String[] args = new String[] { - "src/test/resources/feedback", + "models/aeif_cond_alpha.nestml", "--target", outputPath.toString()}; new NestmlFrontend().start(args); diff --git a/src/test/java/org/nest/integration/SymPyScriptEvaluatorTest.java b/src/test/java/org/nest/integration/SymPyScriptEvaluatorTest.java index 7c760a107..0ab65f9bc 100644 --- a/src/test/java/org/nest/integration/SymPyScriptEvaluatorTest.java +++ b/src/test/java/org/nest/integration/SymPyScriptEvaluatorTest.java @@ -75,7 +75,9 @@ private void generateAndEvaluate(final String pathToModel) throws IOException { final SymPyScriptEvaluator evaluator = new SymPyScriptEvaluator(); assertTrue(evaluator.evaluateScript(generatedScript.get())); - assertTrue(Files.exists(Paths.get(SYMPY_OUTPUT.toString(), TransformerBase.SOLVER_TYPE))); + assertTrue(Files.exists(Paths.get( + SYMPY_OUTPUT.toString(), + root.get().getNeurons().get(0).getName() + "." + TransformerBase.SOLVER_TYPE))); } } diff --git a/src/test/java/org/nest/mocks/PSCMock.java b/src/test/java/org/nest/mocks/PSCMock.java index 8b60d26a0..1e89cbdb0 100644 --- a/src/test/java/org/nest/mocks/PSCMock.java +++ b/src/test/java/org/nest/mocks/PSCMock.java @@ -23,18 +23,18 @@ public class PSCMock extends OdeProcessor { private final static String MOCK_RESOURCE_PATH = "src/test/resources/codegeneration/sympy/psc/"; @Override - protected ASTNeuron handleNeuronWithODE(final ASTNeuron root, ASTNESTMLCompilationUnit artifactRoot, final Path outputBase) { + protected ASTNeuron handleNeuronWithODE(final ASTNeuron astNeuron, ASTNESTMLCompilationUnit artifactRoot, final Path outputBase) { Log.trace("Uses PSC mock", this.getClass().getName()); return getLinearSolutionTransformer().addExactSolution( - root, - Paths.get(MOCK_RESOURCE_PATH, LinearSolutionTransformer.P30_FILE), - Paths.get(MOCK_RESOURCE_PATH, LinearSolutionTransformer.PSC_INITIAL_VALUE_FILE), - Paths.get(MOCK_RESOURCE_PATH, LinearSolutionTransformer.STATE_VARIABLES_FILE), - Paths.get(MOCK_RESOURCE_PATH, LinearSolutionTransformer.PROPAGATOR_MATRIX_FILE), - Paths.get(MOCK_RESOURCE_PATH, LinearSolutionTransformer.PROPAGATOR_STEP_FILE), - Paths.get(MOCK_RESOURCE_PATH, LinearSolutionTransformer.STATE_VECTOR_TMP_DECLARATIONS_FILE), - Paths.get(MOCK_RESOURCE_PATH, LinearSolutionTransformer.STATE_VECTOR_UPDATE_STEPS_FILE), - Paths.get(MOCK_RESOURCE_PATH, LinearSolutionTransformer.STATE_VECTOR_TMP_BACK_ASSIGNMENTS_FILE) + astNeuron, + Paths.get(MOCK_RESOURCE_PATH, astNeuron.getName() + "." + LinearSolutionTransformer.P30_FILE), + Paths.get(MOCK_RESOURCE_PATH, astNeuron.getName() + "." + LinearSolutionTransformer.PSC_INITIAL_VALUE_FILE), + Paths.get(MOCK_RESOURCE_PATH, astNeuron.getName() + "." + LinearSolutionTransformer.STATE_VARIABLES_FILE), + Paths.get(MOCK_RESOURCE_PATH, astNeuron.getName() + "." + LinearSolutionTransformer.PROPAGATOR_MATRIX_FILE), + Paths.get(MOCK_RESOURCE_PATH, astNeuron.getName() + "." + LinearSolutionTransformer.PROPAGATOR_STEP_FILE), + Paths.get(MOCK_RESOURCE_PATH, astNeuron.getName() + "." + LinearSolutionTransformer.STATE_VECTOR_TMP_DECLARATIONS_FILE), + Paths.get(MOCK_RESOURCE_PATH, astNeuron.getName() + "." + LinearSolutionTransformer.STATE_VECTOR_UPDATE_STEPS_FILE), + Paths.get(MOCK_RESOURCE_PATH, astNeuron.getName() + "." + LinearSolutionTransformer.STATE_VECTOR_TMP_BACK_ASSIGNMENTS_FILE) ); } diff --git a/src/test/resources/codegeneration/iaf_psc_alpha_three_buffers.nestml b/src/test/resources/codegeneration/iaf_psc_alpha_three_buffers.nestml index 90b25e4b7..36171fcec 100644 --- a/src/test/resources/codegeneration/iaf_psc_alpha_three_buffers.nestml +++ b/src/test/resources/codegeneration/iaf_psc_alpha_three_buffers.nestml @@ -1,4 +1,4 @@ -neuron iaf_psc_alpha_three_buffers: +neuron iaf_psc_alpha_neuron: state: V_abs mV diff --git a/src/test/resources/codegeneration/sympy/delta/P30.tmp b/src/test/resources/codegeneration/sympy/delta/iaf_psc_delta_neuron.P30.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/delta/P30.tmp rename to src/test/resources/codegeneration/sympy/delta/iaf_psc_delta_neuron.P30.tmp diff --git a/src/test/resources/codegeneration/sympy/delta/propagator.step.tmp b/src/test/resources/codegeneration/sympy/delta/iaf_psc_delta_neuron.propagator.step.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/delta/propagator.step.tmp rename to src/test/resources/codegeneration/sympy/delta/iaf_psc_delta_neuron.propagator.step.tmp diff --git a/src/test/resources/codegeneration/sympy/delta/solverType.tmp b/src/test/resources/codegeneration/sympy/delta/iaf_psc_delta_neuron.solverType.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/delta/solverType.tmp rename to src/test/resources/codegeneration/sympy/delta/iaf_psc_delta_neuron.solverType.tmp diff --git a/src/test/resources/codegeneration/sympy/psc/P30.tmp b/src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.P30.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/psc/P30.tmp rename to src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.P30.tmp diff --git a/src/test/resources/codegeneration/sympy/psc/propagator.matrix.tmp b/src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.propagator.matrix.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/psc/propagator.matrix.tmp rename to src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.propagator.matrix.tmp diff --git a/src/test/resources/codegeneration/sympy/psc/propagator.step.tmp b/src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.propagator.step.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/psc/propagator.step.tmp rename to src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.propagator.step.tmp diff --git a/src/test/resources/codegeneration/sympy/psc/pscInitialValues.tmp b/src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.pscInitialValues.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/psc/pscInitialValues.tmp rename to src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.pscInitialValues.tmp diff --git a/src/test/resources/codegeneration/sympy/psc/solverType.tmp b/src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.solverType.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/psc/solverType.tmp rename to src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.solverType.tmp diff --git a/src/test/resources/codegeneration/sympy/psc/state.variables.tmp b/src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.state.variables.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/psc/state.variables.tmp rename to src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.state.variables.tmp diff --git a/src/test/resources/codegeneration/sympy/psc/state.vector.tmp.back.assignments.tmp b/src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.state.vector.tmp.back.assignments.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/psc/state.vector.tmp.back.assignments.tmp rename to src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.state.vector.tmp.back.assignments.tmp diff --git a/src/test/resources/codegeneration/sympy/psc/state.vector.tmp.declarations.tmp b/src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.state.vector.tmp.declarations.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/psc/state.vector.tmp.declarations.tmp rename to src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.state.vector.tmp.declarations.tmp diff --git a/src/test/resources/codegeneration/sympy/psc/state.vector.update.steps.tmp b/src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.state.vector.update.steps.tmp similarity index 100% rename from src/test/resources/codegeneration/sympy/psc/state.vector.update.steps.tmp rename to src/test/resources/codegeneration/sympy/psc/iaf_psc_alpha_neuron.state.vector.update.steps.tmp diff --git a/src/test/resources/command_line_base/cli_example.nestml b/src/test/resources/command_line_base/cli_example.nestml index ae62936d5..83469a315 100644 --- a/src/test/resources/command_line_base/cli_example.nestml +++ b/src/test/resources/command_line_base/cli_example.nestml @@ -1,4 +1,4 @@ -neuron iaf_psc_alpha_nestml: +neuron iaf_psc_alpha_neuron: state: V_abs mV diff --git a/src/test/resources/feedback/rc_alpha_response.nestml b/src/test/resources/feedback/rc_alpha_response.nestml index 45ac545b7..28b45a7fc 100644 --- a/src/test/resources/feedback/rc_alpha_response.nestml +++ b/src/test/resources/feedback/rc_alpha_response.nestml @@ -8,7 +8,7 @@ neuron rc_alpha_response: C_m pF = 291 pF tau_syn ms = 1 ms tau_m ms = 10 ms - V_th mV = 120 mV + V_th mV = 120 mV**-1 end equations: