def __init__(self, model, keysAsCanonicalNames, **kwargs): """ :param model: daeModel-derived object :param keysAsCanonicalNames: Boolean (True if the keys are canonical names) :param **kwargs: python dictionaries containing parameters values, initial conditions, etc. * parameters -- python dictionary: 'canonical_name' : (value,units) (default: empty dict) * initial_conditions -- python dictionary: 'canonical_name' : (value,units) (default: empty dict) * active_regimes -- python dictionary: 'canonical_name' : string (default: empty dict) * variables_to_report -- python dictionary: 'canonical_name' : boolean (default: empty dict) * analog_ports_expressions -- python dictionary: 'canonical_name' : string (default: empty dict) * event_ports_expressions -- python dictionary: 'canonical_name' : string) (default: empty dict) * analog_ports_expression_parser -- ExpressionParser object (default: None) * values_expression_parser -- ExpressionParser object (default: None) * random_number_generators -- python dictionary: 'name': ninemlRNG object (default: empty dict) :raises: RuntimeError """ self.model = model self.keysAsCanonicalNames = keysAsCanonicalNames # Is there a problem if these dictionaries contain unicode strings? # (if the input originated from the web form) self._parameters = kwargs.get('parameters', {}) self._initial_conditions = kwargs.get('initial_conditions', {}) self._active_regimes = kwargs.get('active_regimes', {}) self._variables_to_report = kwargs.get('variables_to_report', {}) self._analog_ports_expressions = kwargs.get('analog_ports_expressions', {}) self._event_ports_expressions = kwargs.get('event_ports_expressions', {}) self._random_number_generators = kwargs.get('random_number_generators', {}) self.intervals = {} self.debug = False # Initialize reduce ports for portName, expression in list( self._analog_ports_expressions.items()): if not self.keysAsCanonicalNames: portName = self.model.CanonicalName + '.' + portName port = getObjectFromCanonicalName(self.model, portName, look_for_ports=True, look_for_reduceports=True) if port == None: if self.debug: print( 'Warning: Could not locate port {0}'.format(portName)) continue if isinstance(port, ninemlReduceAnalogPort): if len(port.Ports) != 0: raise RuntimeError( 'The reduce port {0} is connected and cannot be set a value' .format(portName)) a_port = port.addPort() elif isinstance(port, ninemlAnalogPort): pass
def SetUpParametersAndDomains(self): """ Sets the parameter values. Called automatically by the simulation. It requires two passes through the list of parameters: #. Set the values that are simple numerical values. #. Set the values that require parsing and (probably) depend on the values of parameters with the simple numerical values. :rtype: None :raises: RuntimeError """ __values_expression_parser__ = getParametersValuesInitialConditionsExpressionParserIdentifiers( self.model) numerical_values = {} expression_values = {} # First create two dictionaries (numerical_values, expression_values) for paramName, value in list(self._parameters.items()): if not self.keysAsCanonicalNames: paramName = self.model.CanonicalName + '.' + paramName parameter = getObjectFromCanonicalName(self.model, paramName, look_for_parameters=True) if parameter == None: if self.debug: print('Warning: Could not locate parameter {0}'.format( paramName)) continue if (isinstance(value, (long, int, float)) or (isinstance(value, tuple) and isinstance(value[0], (long, int, float)))): numerical_values[paramName] = parameter, value else: expression_values[paramName] = parameter, value # First set the parameters with simple numerical values for paramName, (parameter, value) in list(numerical_values.items()): v = self._getValue(value, paramName) parameter.SetValue(v) # Then set the parameters with expressions as values for paramName, (parameter, expression) in list(expression_values.items()): v = self._getValue(expression, paramName) parameter.SetValue(v)
def __init__(self, model, keysAsCanonicalNames, **kwargs): """ :param model: daeModel-derived object :param keysAsCanonicalNames: Boolean (True if the keys are canonical names) :param **kwargs: python dictionaries containing parameters values, initial conditions, etc. * parameters -- python dictionary: 'canonical_name' : (value,units) (default: empty dict) * initial_conditions -- python dictionary: 'canonical_name' : (value,units) (default: empty dict) * active_regimes -- python dictionary: 'canonical_name' : string (default: empty dict) * variables_to_report -- python dictionary: 'canonical_name' : boolean (default: empty dict) * analog_ports_expressions -- python dictionary: 'canonical_name' : string (default: empty dict) * event_ports_expressions -- python dictionary: 'canonical_name' : string) (default: empty dict) * analog_ports_expression_parser -- ExpressionParser object (default: None) * values_expression_parser -- ExpressionParser object (default: None) * random_number_generators -- python dictionary: 'name': ninemlRNG object (default: empty dict) :raises: RuntimeError """ self.model = model self.keysAsCanonicalNames = keysAsCanonicalNames # Is there a problem if these dictionaries contain unicode strings? # (if the input originated from the web form) self._parameters = kwargs.get('parameters', {}) self._initial_conditions = kwargs.get('initial_conditions', {}) self._active_regimes = kwargs.get('active_regimes', {}) self._variables_to_report = kwargs.get('variables_to_report', {}) self._analog_ports_expressions = kwargs.get('analog_ports_expressions', {}) self._event_ports_expressions = kwargs.get('event_ports_expressions', {}) self._random_number_generators = kwargs.get('random_number_generators', {}) self.intervals = {} self.debug = False # Initialize reduce ports for portName, expression in list(self._analog_ports_expressions.items()): if not self.keysAsCanonicalNames: portName = self.model.CanonicalName + '.' + portName port = getObjectFromCanonicalName(self.model, portName, look_for_ports = True, look_for_reduceports = True) if port == None: if self.debug: print('Warning: Could not locate port {0}'.format(portName)) continue if isinstance(port, ninemlReduceAnalogPort): if len(port.Ports) != 0: raise RuntimeError('The reduce port {0} is connected and cannot be set a value'.format(portName)) a_port = port.addPort() elif isinstance(port, ninemlAnalogPort): pass
def SetUpParametersAndDomains(self): """ Sets the parameter values. Called automatically by the simulation. It requires two passes through the list of parameters: #. Set the values that are simple numerical values. #. Set the values that require parsing and (probably) depend on the values of parameters with the simple numerical values. :rtype: None :raises: RuntimeError """ __values_expression_parser__ = getParametersValuesInitialConditionsExpressionParserIdentifiers(self.model) numerical_values = {} expression_values = {} # First create two dictionaries (numerical_values, expression_values) for paramName, value in list(self._parameters.items()): if not self.keysAsCanonicalNames: paramName = self.model.CanonicalName + '.' + paramName parameter = getObjectFromCanonicalName(self.model, paramName, look_for_parameters = True) if parameter == None: if self.debug: print('Warning: Could not locate parameter {0}'.format(paramName)) continue if (isinstance(value, (long, int, float)) or (isinstance(value, tuple) and isinstance(value[0], (long, int, float)))): numerical_values[paramName] = parameter, value else: expression_values[paramName] = parameter, value # First set the parameters with simple numerical values for paramName, (parameter, value) in list(numerical_values.items()): v = self._getValue(value, paramName) parameter.SetValue(v) # Then set the parameters with expressions as values for paramName, (parameter, expression) in list(expression_values.items()): v = self._getValue(expression, paramName) parameter.SetValue(v)
def SetUpVariables(self): """ Sets the initial conditions and other stuff. Called automatically by the simulation. It requires two passes through the list of variables: #. Set the initial conditions that are simple numerical values. #. Set the initial conditions that require parsing and (probably) depend on the values of parameters/variables with the simple numerical values. :rtype: None :raises: RuntimeError """ numerical_values = {} expression_values = {} # First create two dictionaries (numerical_values, expression_values) for varName, value in list(self._initial_conditions.items()): if not self.keysAsCanonicalNames: varName = self.model.CanonicalName + '.' + varName variable = getObjectFromCanonicalName(self.model, varName, look_for_variables=True) if variable == None: if self.debug: print('Warning: Could not locate variable {0}'.format( varName)) continue if (isinstance(value, (long, int, float)) or (isinstance(value, tuple) and isinstance(value[0], (long, int, float)))): numerical_values[varName] = variable, value else: expression_values[varName] = variable, value # First set the parameters with simple numerical values for varName, (variable, value) in list(numerical_values.items()): v = self._getValue(value, varName) variable.SetInitialCondition(v) # Then set the parameters with expressions as values for varName, (variable, expression) in list(expression_values.items()): v = self._getValue(expression, varName) variable.SetInitialCondition(v) for portName, expression in list( self._analog_ports_expressions.items()): if not self.keysAsCanonicalNames: portName = self.model.CanonicalName + '.' + portName if expression == None or expression == '': raise RuntimeError( 'The analog port {0} is not connected and no value has been provided' .format(portName)) port = getObjectFromCanonicalName(self.model, portName, look_for_ports=True, look_for_reduceports=True) if port == None: if self.debug: print( 'Warning: Could not locate port {0}'.format(portName)) continue value = float( __analog_ports_expression_parser__.parse_and_evaluate( expression)) if isinstance(port, ninemlAnalogPort): port.value.AssignValue(value) elif isinstance(port, ninemlReduceAnalogPort): for a_port in port.Ports: a_port.value.AssignValue(value) else: raise RuntimeError('Unknown port object: {0}'.format(portName)) if self.debug: print( ' --> Assign the value of the port variable: {0} to {1} (evaluated value: {2})' .format(portName, expression, value)) for portName, expression in list( self._event_ports_expressions.items()): if not self.keysAsCanonicalNames: portName = self.model.CanonicalName + '.' + portName if expression == None or expression == '': continue port = getObjectFromCanonicalName(self.model, portName, look_for_eventports=True) if port == None: if self.debug: print('Warning: Could not locate event port {0}'.format( portName)) continue str_values = expression.split(',') for item in str_values: try: value = float(item) except ValueError: raise RuntimeError( 'Cannot convert: {0} to floating point value in the event port expression: {1}' .format(item, expression)) # ACHTUNG, ACHTUNG!!! At this point self.intervals contain only event emit time points!! if value in self.intervals: data = self.intervals[value] else: data = [] data.append(port) self.intervals[value] = data if self.debug: print(' --> Event port {0} triggers at: {1}'.format( portName, expression)) for modelName, stateName in list(self._active_regimes.items()): if not self.keysAsCanonicalNames: modelName = self.model.CanonicalName + '.' + modelName stateName = str(stateName) stn = getObjectFromCanonicalName(self.model, modelName + '.' + ninemlSTNRegimesName, look_for_stns=True) if stn == None: if self.debug: print('Warning: Could not locate STN {0}'.format( ninemlSTNRegimesName)) continue if self.debug: print( ' --> Set the active state in the model: {0} to: {1}'. format(modelName, stateName), 0) stn.ActiveState = stateName # This should be False by default self.model.SetReportingOn(False) for varName, value in list(self._variables_to_report.items()): if not self.keysAsCanonicalNames: varName = self.model.CanonicalName + '.' + varName if value: variable = getObjectFromCanonicalName(self.model, varName, look_for_variables=True) if variable == None: if self.debug: print('Warning: Could not locate variable {0}'.format( varName)) continue if self.debug: print(' --> Report the variable: {0}'.format(varName), 0) variable.ReportingOn = True
def SetUpVariables(self): """ Sets the initial conditions and other stuff. Called automatically by the simulation. It requires two passes through the list of variables: #. Set the initial conditions that are simple numerical values. #. Set the initial conditions that require parsing and (probably) depend on the values of parameters/variables with the simple numerical values. :rtype: None :raises: RuntimeError """ numerical_values = {} expression_values = {} # First create two dictionaries (numerical_values, expression_values) for varName, value in list(self._initial_conditions.items()): if not self.keysAsCanonicalNames: varName = self.model.CanonicalName + '.' + varName variable = getObjectFromCanonicalName(self.model, varName, look_for_variables = True) if variable == None: if self.debug: print('Warning: Could not locate variable {0}'.format(varName)) continue if (isinstance(value, (long, int, float)) or (isinstance(value, tuple) and isinstance(value[0], (long, int, float)))): numerical_values[varName] = variable, value else: expression_values[varName] = variable, value # First set the parameters with simple numerical values for varName, (variable, value) in list(numerical_values.items()): v = self._getValue(value, varName) variable.SetInitialCondition(v) # Then set the parameters with expressions as values for varName, (variable, expression) in list(expression_values.items()): v = self._getValue(expression, varName) variable.SetInitialCondition(v) for portName, expression in list(self._analog_ports_expressions.items()): if not self.keysAsCanonicalNames: portName = self.model.CanonicalName + '.' + portName if expression == None or expression == '': raise RuntimeError('The analog port {0} is not connected and no value has been provided'.format(portName)) port = getObjectFromCanonicalName(self.model, portName, look_for_ports = True, look_for_reduceports = True) if port == None: if self.debug: print('Warning: Could not locate port {0}'.format(portName)) continue value = float(__analog_ports_expression_parser__.parse_and_evaluate(expression)) if isinstance(port, ninemlAnalogPort): port.value.AssignValue(value) elif isinstance(port, ninemlReduceAnalogPort): for a_port in port.Ports: a_port.value.AssignValue(value) else: raise RuntimeError('Unknown port object: {0}'.format(portName)) if self.debug: print(' --> Assign the value of the port variable: {0} to {1} (evaluated value: {2})'.format(portName, expression, value)) for portName, expression in list(self._event_ports_expressions.items()): if not self.keysAsCanonicalNames: portName = self.model.CanonicalName + '.' + portName if expression == None or expression == '': continue port = getObjectFromCanonicalName(self.model, portName, look_for_eventports = True) if port == None: if self.debug: print('Warning: Could not locate event port {0}'.format(portName)) continue str_values = expression.split(',') for item in str_values: try: value = float(item) except ValueError: raise RuntimeError('Cannot convert: {0} to floating point value in the event port expression: {1}'.format(item, expression)) # ACHTUNG, ACHTUNG!!! At this point self.intervals contain only event emit time points!! if value in self.intervals: data = self.intervals[value] else: data = [] data.append(port) self.intervals[value] = data if self.debug: print(' --> Event port {0} triggers at: {1}'.format(portName, expression)) for modelName, stateName in list(self._active_regimes.items()): if not self.keysAsCanonicalNames: modelName = self.model.CanonicalName + '.' + modelName stateName = str(stateName) stn = getObjectFromCanonicalName(self.model, modelName + '.' + ninemlSTNRegimesName, look_for_stns = True) if stn == None: if self.debug: print('Warning: Could not locate STN {0}'.format(ninemlSTNRegimesName)) continue if self.debug: print(' --> Set the active state in the model: {0} to: {1}'.format(modelName, stateName), 0) stn.ActiveState = stateName # This should be False by default self.model.SetReportingOn(False) for varName, value in list(self._variables_to_report.items()): if not self.keysAsCanonicalNames: varName = self.model.CanonicalName + '.' + varName if value: variable = getObjectFromCanonicalName(self.model, varName, look_for_variables = True) if variable == None: if self.debug: print('Warning: Could not locate variable {0}'.format(varName)) continue if self.debug: print(' --> Report the variable: {0}'.format(varName), 0) variable.ReportingOn = True