Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
CellMLToNektar.processors.ModelModifier Class Reference
Inheritance diagram for CellMLToNektar.processors.ModelModifier:
Inheritance graph
[legend]
Collaboration diagram for CellMLToNektar.processors.ModelModifier:
Collaboration graph
[legend]

Public Member Functions

def __init__
 
def finalize
 
def create_new_component
 
def connect_variables
 
def remove_connection
 
def remove_connections
 
def add_variable
 
def add_units
 
def add_expr_to_comp
 
def remove_expr
 
def remove_definition
 
def del_attr
 
def set_units_converter
 
def get_units_converter
 

Public Attributes

 model
 
 connections_made
 

Private Member Functions

def _clear_model_caches
 
def _make_connection
 
def _find_connection_element
 
def _create_connection_element
 
def _update_connections
 
def _find_common_tail
 
def _parent_path
 
def _process_operator
 
def _find_or_create_variable
 
def _get_units_object
 
def _uniquify_var_name
 
def _uniquify_name
 
def _convert_initial_value
 

Private Attributes

 _units_converter
 

Detailed Description

Base class supporting common model modification functionality.

This class contains the logic to deal with adding/deleting variables, components, equations, etc.
and connecting things up.  It also handles re-analysing the model when modifications have been
completed to ensure that PyCml's internal data structures are up-to-date.

Instances should be created with the model to modify as a single parameter.  Once all
modifications have been completed, the finalize method must be called to ensure later
processing of the model (e.g. code generation) will succeed.

Definition at line 47 of file processors.py.

Constructor & Destructor Documentation

def CellMLToNektar.processors.ModelModifier.__init__ (   self,
  model 
)
Constructor.

Definition at line 58 of file processors.py.

58 
59  def __init__(self, model):
60  """Constructor."""
61  self.model = model
62  self._units_converter = None
63  self.connections_made = set()

Member Function Documentation

def CellMLToNektar.processors.ModelModifier._clear_model_caches (   self)
private
Clear cached links in the model, since we'll need to recompute many of them
once we've finished modifying it.  Also clears dependency information.

Definition at line 100 of file processors.py.

References CellMLToNektar.processors.ModelModifier.model.

Referenced by CellMLToNektar.processors.ModelModifier.finalize().

101  def _clear_model_caches(self):
102  """
103  Clear cached links in the model, since we'll need to recompute many of them
104  once we've finished modifying it. Also clears dependency information.
105  """
106  for comp in getattr(self.model, u'component', []):
107  for math in getattr(comp, u'math', []):
108  math._unset_cached_links()
109  for var in self.model.get_all_variables():
110  var.clear_dependency_info()
111  assignment_exprs = self.model.search_for_assignments()
112  for expr in assignment_exprs:
113  expr.clear_dependency_info()
def CellMLToNektar.processors.ModelModifier._convert_initial_value (   self,
  var,
  units,
  do_conversion = True 
)
private
Convert any initial value of the given variable into the given units.

If there is no initial value, returns None.
If there is no units converter, leaves the initial_value unchanged.

Definition at line 513 of file processors.py.

References CellMLToNektar.processors.ModelModifier._units_converter, and CellMLToNektar.pycml.equals().

Referenced by CellMLToNektar.processors.InterfaceGenerator.add_input().

514  def _convert_initial_value(self, var, units, do_conversion=True):
515  """Convert any initial value of the given variable into the given units.
516 
517  If there is no initial value, returns None.
518  If there is no units converter, leaves the initial_value unchanged.
519  """
520  if not hasattr(var, u'initial_value'):
521  return None
522  value = var.initial_value
523  if value and self._units_converter and do_conversion:
524  if not var.get_units().equals(units):
525  try:
526  value = self._units_converter.convert_constant(value, var.get_units(), units, var.component)
527  except EvaluationError, e:
528  raise ModelModificationError("Cannot units-convert initial value as requires run-time information:\n"
529  + str(e))
530  return unicode(value)
531 
532 
def CellMLToNektar.processors.ModelModifier._create_connection_element (   self,
  var1,
  var2 
)
private
Create a connection element connecting the given variables and add to the model.

If there's already a connection element for the relevant pair of components,
we just add another map_variables element to that.

Definition at line 249 of file processors.py.

References CellMLToNektar.processors.ModelModifier._find_connection_element().

Referenced by CellMLToNektar.processors.ModelModifier._make_connection().

250  def _create_connection_element(self, var1, var2):
251  """Create a connection element connecting the given variables and add to the model.
252 
253  If there's already a connection element for the relevant pair of components,
254  we just add another map_variables element to that.
255  """
256  conn, swap = self._find_connection_element(var1, var2)
257  if conn:
258  if swap:
259  var1, var2 = var2, var1
260  else:
261  conn = var1.xml_create_element(u'connection', NSS[u'cml'])
262  mapc = var1.xml_create_element(u'map_components', NSS[u'cml'],
263  attributes={u'component_1': var1.component.name,
264  u'component_2': var2.component.name})
265  conn.xml_append(mapc)
266  self.model.xml_append(conn)
267  mapv = var1.xml_create_element(u'map_variables', NSS[u'cml'],
268  attributes={u'variable_1': var1.name,
269  u'variable_2': var2.name})
270  conn.xml_append(mapv)
def CellMLToNektar.processors.ModelModifier._find_common_tail (   self,
  l1,
  l2 
)
private
Find the first element at which both lists are identical from then on.

Definition at line 327 of file processors.py.

Referenced by CellMLToNektar.processors.ModelModifier.connect_variables().

328  def _find_common_tail(self, l1, l2):
329  """Find the first element at which both lists are identical from then on."""
330  i = -1
331  try:
332  while l1[i] == l2[i]:
333  i -= 1
334  except IndexError:
335  # One list is the tail of the other
336  pass
337  # i now gives the last differing element
338  assert i < -1
339  return i+1
def CellMLToNektar.processors.ModelModifier._find_connection_element (   self,
  var1,
  var2 
)
private
Find any connection element containing a connection of the given variables.

Returns a pair, the first element of which is either the element or None, and the
second of which is a boolean indicating whether the variables need to be swapped
in order to match the order of the components in the connection.

Definition at line 228 of file processors.py.

References CellMLToNektar.processors.ModelModifier.model.

Referenced by CellMLToNektar.processors.ModelModifier._create_connection_element(), and CellMLToNektar.processors.ModelModifier.remove_connection().

229  def _find_connection_element(self, var1, var2):
230  """Find any connection element containing a connection of the given variables.
231 
232  Returns a pair, the first element of which is either the element or None, and the
233  second of which is a boolean indicating whether the variables need to be swapped
234  in order to match the order of the components in the connection.
235  """
236  cn1, cn2 = var1.component.name, var2.component.name
237  cnames = set([cn1, cn2])
238  for conn in getattr(self.model, u'connection', []):
239  mc = conn.map_components
240  if set([mc.component_1, mc.component_2]) == cnames:
241  break
242  else:
243  conn = None
244  if conn:
245  swap = conn.map_components.component_1 == cn2
246  else:
247  swap = False
248  return conn, swap
def CellMLToNektar.processors.ModelModifier._find_or_create_variable (   self,
  cname,
  vname,
  source 
)
private
Find a given variable in the model, creating it if necessary.

We look for a variable in the component named cname with the same name as the source.
If it doesn't exist, a variable named vname will be created in that component (unless
it already exists).
The variable will become a mapped variable with the given source.
Hence if it is created it will have the same units.

Definition at line 359 of file processors.py.

References CellMLToNektar.processors.ModelModifier.add_variable().

Referenced by CellMLToNektar.processors.ModelModifier._make_connection().

360  def _find_or_create_variable(self, cname, vname, source):
361  """Find a given variable in the model, creating it if necessary.
362 
363  We look for a variable in the component named cname with the same name as the source.
364  If it doesn't exist, a variable named vname will be created in that component (unless
365  it already exists).
366  The variable will become a mapped variable with the given source.
367  Hence if it is created it will have the same units.
368  """
369  try:
370  var = self.model.get_variable_by_name(cname, source.name)
371  raise KeyError()
372  except KeyError:
373  # Have we created it already?
374  try:
375  var = self.model.get_variable_by_name(cname, vname)
376  except KeyError:
377  # Create it and add to model
378  units = source.component.get_units_by_name(source.units)
379  var = self.add_variable(cname, vname, units)
380  return var
def CellMLToNektar.processors.ModelModifier._get_units_object (   self,
  units 
)
private
Helper function to convert a units specification into a cellml_units object.

The input can be a cellml_units object, in which case we just return it.
However, it can also be a serialised CellML units definition, in which case it
will be parsed to create the object.

Definition at line 394 of file processors.py.

References CellMLToNektar.pycml.amara_parse_cellml().

Referenced by CellMLToNektar.processors.InterfaceGenerator.add_input(), CellMLToNektar.processors.InterfaceGenerator.add_output(), and CellMLToNektar.processors.InterfaceGenerator.add_output_function().

395  def _get_units_object(self, units):
396  """Helper function to convert a units specification into a cellml_units object.
397 
398  The input can be a cellml_units object, in which case we just return it.
399  However, it can also be a serialised CellML units definition, in which case it
400  will be parsed to create the object.
401  """
402  if isinstance(units, cellml_units):
403  # We're done
404  pass
405  else:
406  units = amara_parse_cellml(unicode(units))
407  assert isinstance(units, cellml_units)
408  return units
def amara_parse_cellml
Definition: pycml.py:191
def CellMLToNektar.processors.ModelModifier._make_connection (   self,
  src_var,
  target_comp,
  target_vname 
)
private
Make a connection from a source variable to a given component and suggested local name.

Note that in the case that both variables already exist and are connected, the existing
connection is allowed to flow in either direction.

Definition at line 180 of file processors.py.

References CellMLToNektar.processors.ModelModifier._create_connection_element(), CellMLToNektar.processors.ModelModifier._find_or_create_variable(), and CellMLToNektar.processors.ModelModifier._make_connection().

Referenced by CellMLToNektar.processors.ModelModifier._make_connection(), and CellMLToNektar.processors.ModelModifier.connect_variables().

181  def _make_connection(self, src_var, target_comp, target_vname):
182  """Make a connection from a source variable to a given component and suggested local name.
183 
184  Note that in the case that both variables already exist and are connected, the existing
185  connection is allowed to flow in either direction.
186  """
187  src_comp = src_var.component
188  target_var = self._find_or_create_variable(target_comp.name, target_vname, src_var)
189  # Sanity check the target variable
190  if (target_var.get_type() == VarTypes.Mapped
191  and target_var.get_source_variable(recurse=True) is src_var.get_source_variable(recurse=True)):
192 # print "Connection exists between", src_var, "and target", target_var
193  return target_var
194  elif target_var.get_type() == VarTypes.Unknown:
195  # We've created this variable, so should be ok, but check for gotchas
196  assert not(hasattr(target_var, u'initial_value'))
197  if src_comp is target_comp.parent():
198  src_if = u'private'
199  target_if = u'public'
200  elif src_comp.parent() is target_comp:
201  src_if = u'public'
202  target_if = u'private'
203  else:
204  assert src_comp.parent() is target_comp.parent()
205  src_if = u'public'
206  target_if = u'public'
207  # One special case: if the src_var is actually obtained from a different
208  # component at this level or above, in which case we should use the real
209  # source, not that given.
210  if getattr(src_var, src_if + u'_interface', u'none') == u'in':
211  src_var = src_var.get_source_variable()
212  # Check and set the interface attributes
213 # print "Connecting source", src_var, src_if, getattr(src_var, src_if + u'_interface', u'none'),
214 # print "to", target_var, target_if, getattr(target_var, target_if + u'_interface', u'none')
215  assert getattr(src_var, src_if + u'_interface', u'none') != u'in'
216  assert getattr(target_var, target_if + u'_interface', u'none') != u'out'
217  src_var.xml_set_attribute((src_if + u'_interface', None), u'out')
218  target_var.xml_set_attribute((target_if + u'_interface', None), u'in')
219  # Create the connection element
220  self._create_connection_element(src_var, target_var)
221  self.connections_made.add(frozenset([src_var, target_var]))
222  # Ensure we handle a later connection attempt between these variables correctly
223  target_var._set_source_variable(src_var)
224  else:
225  # Naming conflict; try again with a different target name
226  return self._make_connection(src_var, target_comp, target_vname + u'_')
227  return target_var
def CellMLToNektar.processors.ModelModifier._parent_path (   self,
  comp 
)
private
Return a path of components from that given to the encapsulation root.

The root is specified by None, since we're really dealing with a forest,
not a tree.

Definition at line 340 of file processors.py.

Referenced by CellMLToNektar.processors.ModelModifier.connect_variables().

341  def _parent_path(self, comp):
342  """Return a path of components from that given to the encapsulation root.
343 
344  The root is specified by None, since we're really dealing with a forest,
345  not a tree.
346  """
347  path = [comp]
348  while comp:
349  path.append(comp.parent())
350  comp = comp.parent()
351  return path
def CellMLToNektar.processors.ModelModifier._process_operator (   self,
  expr,
  operator,
  func,
  args,
  kwargs 
)
private
Apply func to any application of the given operator within the given tree.

Definition at line 352 of file processors.py.

References CellMLToNektar.processors.ModelModifier._process_operator().

Referenced by CellMLToNektar.processors.ModelModifier._process_operator(), and CellMLToNektar.processors.InterfaceGenerator._transform_derivatives_on_rhs().

353  def _process_operator(self, expr, operator, func, *args, **kwargs):
354  """Apply func to any application of the given operator within the given tree."""
355  for elt in self.model.xml_element_children(expr):
356  self._process_operator(elt, operator, func, *args, **kwargs)
357  if isinstance(expr, mathml_apply) and expr.operator().localName == operator:
358  func(expr, *args, **kwargs)
def CellMLToNektar.processors.ModelModifier._uniquify_name (   self,
  name,
  callable 
)
private
Ensure the given name is unique within a particular context.

The context is determined by the given function: it will be passed candidate names to test
for existence, and is expected to throw iff the name is not already used.  Underscores will
be appended to the given name until callable throws, and the resulting unique name returned.

Definition at line 488 of file processors.py.

Referenced by CellMLToNektar.processors.ModelModifier._uniquify_var_name(), and CellMLToNektar.processors.ModelModifier.add_units().

489  def _uniquify_name(self, name, callable):
490  """Ensure the given name is unique within a particular context.
491 
492  The context is determined by the given function: it will be passed candidate names to test
493  for existence, and is expected to throw iff the name is not already used. Underscores will
494  be appended to the given name until callable throws, and the resulting unique name returned.
495  """
496  while True:
497  try:
498  callable(name)
499  name += u'_'
500  except:
501  break
502  return name
def CellMLToNektar.processors.ModelModifier._uniquify_var_name (   self,
  varname,
  comp 
)
private
Ensure varname is unique within the given component.

Underscores will be appended to the name until it is unique.  The unique name will be returned.

Definition at line 481 of file processors.py.

References CellMLToNektar.processors.ModelModifier._uniquify_name().

Referenced by CellMLToNektar.processors.InterfaceGenerator._split_ode().

482  def _uniquify_var_name(self, varname, comp):
483  """Ensure varname is unique within the given component.
484 
485  Underscores will be appended to the name until it is unique. The unique name will be returned.
486  """
487  return self._uniquify_name(varname, comp.get_variable_by_name)
def CellMLToNektar.processors.ModelModifier._update_connections (   self,
  oldVar,
  newVar 
)
private
Change all variables connected to oldVar to be mapped to newVar instead.

Definition at line 314 of file processors.py.

References CellMLToNektar.processors.ModelModifier.connect_variables(), CellMLToNektar.processors.ModelModifier.del_attr(), and CellMLToNektar.processors.ModelModifier.remove_connections().

Referenced by CellMLToNektar.processors.InterfaceGenerator.add_input().

315  def _update_connections(self, oldVar, newVar):
316  """Change all variables connected to oldVar to be mapped to newVar instead."""
317  vars = [v for v in self.model.get_all_variables() if v.get_source_variable(True) is oldVar]
318  # Remove old connections, including interfaces and types so creating the new connection works
319  for v in vars:
320  self.remove_connections(v)
321  self.del_attr(v, u'public_interface')
322  self.del_attr(v, u'private_interface')
323  v.clear_dependency_info()
324  # Create new connections
325  for v in vars:
326  self.connect_variables(newVar, v)
def CellMLToNektar.processors.ModelModifier.add_expr_to_comp (   self,
  comp,
  expr 
)
Add an expression to the mathematics in the given component.

comp may be a cellml_component instance or a component name.

Definition at line 434 of file processors.py.

Referenced by CellMLToNektar.processors.InterfaceGenerator._split_ode(), CellMLToNektar.processors.InterfaceGenerator.add_output_function(), CellMLToNektar.processors.UnitsConverter.convert_constant(), CellMLToNektar.processors.UnitsConverter.convert_mapping(), and CellMLToNektar.processors.InterfaceGenerator.make_var_computed_constant().

435  def add_expr_to_comp(self, comp, expr):
436  """Add an expression to the mathematics in the given component.
437 
438  comp may be a cellml_component instance or a component name.
439  """
440  if not isinstance(comp, cellml_component):
441  comp = self.model.get_component_by_name(comp)
442  if not hasattr(comp, u'math'):
443  # Create the math element
444  math = comp.xml_create_element(u'math', NSS[u'm'])
445  comp.xml_append(math)
446  # Append this expression
447  comp.math.xml_append(expr)
def CellMLToNektar.processors.ModelModifier.add_units (   self,
  units 
)
Add a units definition to the model, if it doesn't already exist.

If the definition isn't in the model, at whole-model level, it will be added.  If the same
definition is already available, however, that definition should be used by preference.
Will return the actual units object to use.

Definition at line 409 of file processors.py.

References CellMLToNektar.processors.ModelModifier._uniquify_name(), and CellMLToNektar.processors.ModelModifier.add_units().

Referenced by CellMLToNektar.processors.ModelModifier.add_units(), CellMLToNektar.processors.ModelModifier.add_variable(), and CellMLToNektar.processors.UnitsConverter.convert_constant().

410  def add_units(self, units):
411  """Add a units definition to the model, if it doesn't already exist.
412 
413  If the definition isn't in the model, at whole-model level, it will be added. If the same
414  definition is already available, however, that definition should be used by preference.
415  Will return the actual units object to use.
416  """
417  units = self.model._get_units_obj(units)
418  try:
419  model_units = self.model.get_units_by_name(units.name)
420  except KeyError:
421  model_units = None
422  if model_units:
423  assert units.uniquify_tuple == model_units.uniquify_tuple
424  units = model_units
425  else:
426  units.name = self._uniquify_name(units.name, self.model.get_units_by_name)
427  self.model.add_units(units.name, units)
428  self.model.xml_append(units)
429  # Ensure referenced units exist
430  for unit in getattr(units, u'unit', []):
431  unit._set_units_element(self.add_units(unit.get_units_element()), override=True)
432  unit.units = unit.get_units_element().name
433  return units
def CellMLToNektar.processors.ModelModifier.add_variable (   self,
  comp,
  vname,
  units,
  kwargs 
)
Add a new variable to the given component.

Remaining arguments are as for cellml_variable.create_new.
Returns the new variable object.

Definition at line 381 of file processors.py.

References CellMLToNektar.processors.ModelModifier.add_units().

Referenced by CellMLToNektar.processors.ModelModifier._find_or_create_variable(), CellMLToNektar.processors.InterfaceGenerator._split_ode(), CellMLToNektar.processors.InterfaceGenerator.add_input(), CellMLToNektar.processors.InterfaceGenerator.add_output(), CellMLToNektar.processors.InterfaceGenerator.add_output_function(), and CellMLToNektar.processors.UnitsConverter.convert_mapping().

382  def add_variable(self, comp, vname, units, **kwargs):
383  """Add a new variable to the given component.
384 
385  Remaining arguments are as for cellml_variable.create_new.
386  Returns the new variable object.
387  """
388  if not isinstance(comp, cellml_component):
389  comp = self.model.get_component_by_name(comp)
390  units = self.add_units(units)
391  var = cellml_variable.create_new(comp, vname, units.name, **kwargs)
392  comp._add_variable(var)
393  return var
def CellMLToNektar.processors.ModelModifier.connect_variables (   self,
  source,
  target 
)
Create a connection between the given source and target variables.

The variables are both specified either by a pair (cname,vname), or as cellml_variable objects.
The source variable must exist within the model, whereas the target might not, in
which case it will be created.

Note that in the case that both source and target exist, it might NOT be the case that
target obtains its value from source.  They might already be connected, and source obtains
its value from target.  Or they might both obtain their value from a common source.

If the variable names are not identical, any variables created will have the same name as the
target, if possible.  If there's an existing variable with that name, not connected to the
source, then underscores will be appended to the name to avoid conflicts.  Note that we do
check for variables in intermediate components that have the same name as the source and are
connected to it, to avoid adding unnecessary variables.

Returns the target variable object.

Definition at line 132 of file processors.py.

References CellMLToNektar.processors.ModelModifier._find_common_tail(), CellMLToNektar.processors.ModelModifier._make_connection(), and CellMLToNektar.processors.ModelModifier._parent_path().

Referenced by CellMLToNektar.processors.InterfaceGenerator._transform_derivative_on_rhs(), CellMLToNektar.processors.ModelModifier._update_connections(), CellMLToNektar.processors.InterfaceGenerator.add_output(), and CellMLToNektar.processors.UnitsConverter.modify_rhs().

133  def connect_variables(self, source, target):
134  """Create a connection between the given source and target variables.
135 
136  The variables are both specified either by a pair (cname,vname), or as cellml_variable objects.
137  The source variable must exist within the model, whereas the target might not, in
138  which case it will be created.
139 
140  Note that in the case that both source and target exist, it might NOT be the case that
141  target obtains its value from source. They might already be connected, and source obtains
142  its value from target. Or they might both obtain their value from a common source.
143 
144  If the variable names are not identical, any variables created will have the same name as the
145  target, if possible. If there's an existing variable with that name, not connected to the
146  source, then underscores will be appended to the name to avoid conflicts. Note that we do
147  check for variables in intermediate components that have the same name as the source and are
148  connected to it, to avoid adding unnecessary variables.
149 
150  Returns the target variable object.
151  """
152  if isinstance(source, cellml_variable):
153  src_cname, src_vname = source.component.name, source.name
154  else:
155  src_cname, src_vname = source
156  if isinstance(target, cellml_variable):
157  target_cname, target_vname = target.component.name, target.name
158  else:
159  target_cname, target_vname = target
160  src_comp = self.model.get_component_by_name(src_cname)
161  target_comp = self.model.get_component_by_name(target_cname)
162  if src_comp == target_comp:
163  return target_comp.get_variable_by_name(target_vname)
164  # Determine encapsulation paths from target & source to the root
165  src_path = self._parent_path(src_comp)
166  target_path = self._parent_path(target_comp)
167  # At some point these will share a common path, even if it's just the root itself
168  meeting_index = self._find_common_tail(src_path, target_path)
169  # Construct path from source to target, leaving out the root (None)
170  path = src_path[:meeting_index]
171  if src_path[meeting_index]:
172  path.append(src_path[meeting_index])
173  path.extend(reversed(target_path[:meeting_index]))
174  # Traverse this path, adding connections at each step
175  next_src_var = src_comp.get_variable_by_name(src_vname)
176  for i, src_comp in enumerate(path[:-1]):
177  target_comp = path[i+1]
178  next_src_var = self._make_connection(next_src_var, target_comp, target_vname)
179  return next_src_var
def CellMLToNektar.processors.ModelModifier.create_new_component (   self,
  cname 
)
Create a new component in the model, ensuring the name is unique.

If a component with name cname already exists,
underscores will be added to the component name to make it unique.

Definition at line 114 of file processors.py.

References CellMLToNektar.processors.ModelModifier.model.

Referenced by CellMLToNektar.processors.InterfaceGenerator.get_interface_component().

115  def create_new_component(self, cname):
116  """Create a new component in the model, ensuring the name is unique.
117 
118  If a component with name cname already exists,
119  underscores will be added to the component name to make it unique.
120  """
121  while True:
122  try:
123  self.model.get_component_by_name(cname)
124  cname += u'_'
125  except KeyError:
126  # Component with this name doesn't exist
127  break
128  # Create the component
129  comp = cellml_component.create_new(self.model, cname)
130  self.model._add_component(comp)
131  return comp
def CellMLToNektar.processors.ModelModifier.del_attr (   self,
  elt,
  localName,
  ns = None 
)
Delete an XML attribute from an element, if it exists.

Definition at line 474 of file processors.py.

Referenced by CellMLToNektar.processors.ModelModifier._update_connections(), CellMLToNektar.processors.InterfaceGenerator.add_input(), CellMLToNektar.processors.InterfaceGenerator.add_output(), and CellMLToNektar.processors.ModelModifier.remove_definition().

475  def del_attr(self, elt, localName, ns=None):
476  """Delete an XML attribute from an element, if it exists."""
477  for (pyname, (qname, ns_)) in elt.xml_attributes.items():
478  _, name = SplitQName(qname)
479  if ns_ == ns and name == localName:
480  delattr(elt, pyname)
def CellMLToNektar.processors.ModelModifier.finalize (   self,
  error_handler,
  pre_units_check_hook = None,
  check_units = True 
)
Re-do the model validation steps needed for further processing of the model.

Checks connections, etc. and builds up the dependency graph again, then performs
a topological sort.

If any errors are found during re-validation, the error_handler will be called with the
list.  Warnings are ignored.

TODO: figure out how to determine how much of this is actually needed - InterfaceGenerator
can probably get away with less work.

Definition at line 64 of file processors.py.

References CellMLToNektar.processors.ModelModifier._clear_model_caches().

64 
65  def finalize(self, error_handler, pre_units_check_hook=None, check_units=True):
66  """Re-do the model validation steps needed for further processing of the model.
67 
68  Checks connections, etc. and builds up the dependency graph again, then performs
69  a topological sort.
70 
71  If any errors are found during re-validation, the error_handler will be called with the
72  list. Warnings are ignored.
73 
74  TODO: figure out how to determine how much of this is actually needed - InterfaceGenerator
75  can probably get away with less work.
76  """
77  self._clear_model_caches()
78  # We want to see any errors
79  logging_info = validator.CellMLValidator.setup_logging(show_errors=True, show_warnings=False)
80  # Re-run validation & analysis
81  self.model._check_variable_mappings()
82  if not self.model._cml_validation_errors:
83  assignment_exprs = self.model.search_for_assignments()
84  self.model._check_assigned_vars(assignment_exprs)
85  if not self.model._cml_validation_errors:
86  self.model._classify_variables(assignment_exprs)
87  self.model._order_variables(assignment_exprs)
88  if not self.model._cml_validation_errors and check_units:
89  if callable(pre_units_check_hook):
90  pre_units_check_hook()
91  self.model._check_connection_units(check_for_units_conversions=False)
92  self.model._check_dimensional_consistency(assignment_exprs,
93  xml_context=False,
94  warn_on_units_errors=self.model.get_option('warn_on_units_errors'),
95  check_for_units_conversions=False)
96  if self.model._cml_validation_errors:
97  error_handler(self.model._cml_validation_errors)
98  # Clear up logging
99  validator.CellMLValidator.cleanup_logging(logging_info)
def CellMLToNektar.processors.ModelModifier.get_units_converter (   self)
Get the units converter object, if any has been set.

Definition at line 507 of file processors.py.

References CellMLToNektar.processors.ModelModifier._units_converter.

508  def get_units_converter(self):
509  """Get the units converter object, if any has been set."""
510  if not self._units_converter:
511  raise ModelModificationError("No units converter has been set.")
512  return self._units_converter
def CellMLToNektar.processors.ModelModifier.remove_connection (   self,
  var1,
  var2 
)
Remove a connection between two variables.

Removes the relevant map_variables element.
If this results in an empty connection element, removes that as well.

Definition at line 271 of file processors.py.

References CellMLToNektar.processors.ModelModifier._find_connection_element().

272  def remove_connection(self, var1, var2):
273  """Remove a connection between two variables.
274 
275  Removes the relevant map_variables element.
276  If this results in an empty connection element, removes that as well.
277  """
278  conn, swap = self._find_connection_element(var1, var2)
279  if not conn:
280  raise ModelModificationError("Cannot remove non-existent connection.")
281  if swap:
282  var1, var2 = var2, var1
283  # Find the relevant map_variables element
284  mapv = conn.xml_xpath(u'cml:map_variables[@variable_1="%s" and @variable_2="%s"]'
285  % (var1.name, var2.name))
286  if not mapv:
287  raise ModelModificationError("Cannot remove non-existent connection.")
288  conn.xml_remove_child(mapv[0])
289  if not hasattr(conn, u'map_variables'):
290  conn.xml_parent.xml_remove_child(conn)
def CellMLToNektar.processors.ModelModifier.remove_connections (   self,
  var 
)
Remove all connection elements for the given variable.

Removes each relevant map_variables element.
If this results in an empty connection element, removes that as well.

Definition at line 291 of file processors.py.

References CellMLToNektar.processors.ModelModifier.model.

Referenced by CellMLToNektar.processors.ModelModifier._update_connections().

292  def remove_connections(self, var):
293  """Remove all connection elements for the given variable.
294 
295  Removes each relevant map_variables element.
296  If this results in an empty connection element, removes that as well.
297  """
298  cname, vname = var.component.name, var.name
299  for conn in list(getattr(self.model, u'connection', [])):
300  if cname == conn.map_components.component_1:
301  vid = u'variable_1'
302  elif cname == conn.map_components.component_2:
303  vid = u'variable_2'
304  else:
305  continue
306  for mapv in conn.map_variables:
307  if vname == getattr(mapv, vid, ''):
308  # Found a connection
309  conn.xml_remove_child(mapv)
310  if not hasattr(conn, u'map_variables'):
311  conn.xml_parent.xml_remove_child(conn)
312  # There can't be any more matching map_variables in this connection
313  break
def CellMLToNektar.processors.ModelModifier.remove_definition (   self,
  var,
  keep_initial_value = False 
)
Remove any existing definition (as an equation) of the given variable.

If keep_initial_value is False, then also remove any initial_value attribute.

If the variable is Mapped, throw a ModelModificationError.

Definition at line 456 of file processors.py.

References CellMLToNektar.processors.ModelModifier.del_attr(), and CellMLToNektar.processors.ModelModifier.remove_expr().

Referenced by CellMLToNektar.processors.InterfaceGenerator.make_var_computed_constant(), and CellMLToNektar.processors.InterfaceGenerator.make_var_constant().

457  def remove_definition(self, var, keep_initial_value=False):
458  """Remove any existing definition (as an equation) of the given variable.
459 
460  If keep_initial_value is False, then also remove any initial_value attribute.
461 
462  If the variable is Mapped, throw a ModelModificationError.
463  """
464  if var.get_type() == VarTypes.Mapped:
465  raise ModelModificationError("Cannot remove the equation defining a mapped variable - remove the definition of its source instead")
466  if not keep_initial_value:
467  self.del_attr(var, u'initial_value')
468  # Note: if this is a variable added by a protocol, then it shouldn't have
469  # any dependencies set up yet, so this is a no-op.
470  for dep in var.get_all_expr_dependencies():
471  self.remove_expr(dep)
472  # We know don't know how it will be defined
473  var.clear_dependency_info()
def CellMLToNektar.processors.ModelModifier.remove_expr (   self,
  expr 
)
Remove an expression (ODE or assignment) from its parent.

Definition at line 448 of file processors.py.

Referenced by CellMLToNektar.processors.InterfaceGenerator._split_ode(), CellMLToNektar.processors.UnitsConverter.convert_constant(), and CellMLToNektar.processors.ModelModifier.remove_definition().

449  def remove_expr(self, expr):
450  """Remove an expression (ODE or assignment) from its parent."""
451  assert isinstance(expr, mathml_apply)
452  if expr.xml_parent:
453  expr.xml_parent.safe_remove_child(expr)
454  expr.xml_parent = None # Not done by Amara...
455  return expr
def CellMLToNektar.processors.ModelModifier.set_units_converter (   self,
  converter 
)
Set the object used to units-convert variable initial values.

Definition at line 503 of file processors.py.

References CellMLToNektar.processors.ModelModifier._units_converter.

504  def set_units_converter(self, converter):
505  """Set the object used to units-convert variable initial values."""
506  self._units_converter = converter

Member Data Documentation

CellMLToNektar.processors.ModelModifier._units_converter
private

Definition at line 61 of file processors.py.

Referenced by CellMLToNektar.processors.ModelModifier._convert_initial_value(), CellMLToNektar.processors.ModelModifier.get_units_converter(), and CellMLToNektar.processors.ModelModifier.set_units_converter().

CellMLToNektar.processors.ModelModifier.connections_made

Definition at line 62 of file processors.py.

CellMLToNektar.processors.ModelModifier.model

Definition at line 60 of file processors.py.

Referenced by CellMLToNektar.processors.ModelModifier._clear_model_caches(), CellMLToNektar.processors.ModelModifier._find_connection_element(), CellMLToNektar.pycml.cellml_variable._set_source_variable(), CellMLToNektar.processors.InterfaceGenerator._split_ode(), CellMLToNektar.processors.UnitsConverter.add_all_conversions(), CellMLToNektar.processors.UnitsConverter.add_conversions_for_component(), CellMLToNektar.processors.InterfaceGenerator.add_output_function(), CellMLToNektar.pycml.cellml_variable.add_rdf_annotation(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.code_name(), CellMLToNektar.processors.UnitsConverter.convert_connections(), CellMLToNektar.processors.UnitsConverter.convert_constant(), CellMLToNektar.processors.UnitsConverter.convert_mapping(), CellMLToNektar.processors.ModelModifier.create_new_component(), CellMLToNektar.pycml.cellml_variable.get_rdf_annotation(), CellMLToNektar.pycml.cellml_variable.get_rdf_annotations(), CellMLToNektar.pycml.mathml_apply.get_units(), CellMLToNektar.processors.InterfaceGenerator.make_var_computed_constant(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_backward_euler_mathematics(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_constructor(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_get_i_ionic(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_model_attributes(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_verify_state_variables(), CellMLToNektar.processors.ModelModifier.remove_connections(), CellMLToNektar.pycml.cellml_variable.remove_rdf_annotations(), CellMLToNektar.translators.CellMLTranslator.var_display_name(), and CellMLToNektar.translators.CellMLTranslator.varobj().