Nektar++
Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes | List of all members
CellMLToNektar.pycml.cellml_model Class Reference
Inheritance diagram for CellMLToNektar.pycml.cellml_model:
[legend]

Public Member Functions

def __init__ (self)
 
def __del__ (self)
 
def clean_up (self)
 
def get_config (self, config_attr=None)
 
def get_option (self, option_name)
 
def get_component_by_name (self, compname)
 
def get_variable_by_name (self, compname, varname)
 
def get_variable_by_oxmeta_name (self, name, throw=True)
 
def get_variables_by_ontology_term (self, term)
 
def get_variable_by_cmeta_id (self, cmeta_id)
 
def get_all_variables (self)
 
def validation_error (self, errmsg, level=logging.ERROR)
 
def get_validation_errors (self)
 
def validation_warning (self, errmsg, level=logging.WARNING)
 
def get_validation_warnings (self)
 
def validate (self, xml_context=False, invalid_if_warnings=False, warn_on_units_errors=False, check_for_units_conversions=False, assume_valid=False, **ignored_kwargs)
 
def search_for_assignments (self, comp=None)
 
def build_name_dictionaries (self, rebuild=False)
 
def build_component_hierarchy (self, relationship, namespace=None, name=None, rels=None)
 
def topological_sort (self, node)
 
def get_assignments (self)
 
def clear_assignments (self)
 
def do_binding_time_analysis (self)
 
def get_standard_units (self)
 
def get_all_units (self)
 
def get_units_by_name (self, uname)
 
def add_units (self, name, units)
 
def has_units (self, units)
 
def add_units_conversions (self)
 
def find_state_vars (self)
 
def find_free_vars (self)
 
def calculate_extended_dependencies (self, nodes, prune=[], prune_deps=[], state_vars_depend_on_odes=False, state_vars_examined=set())
 
def is_self_excitatory (self)
 
def xml (self, stream=None, writer=None, **wargs)
 
- Public Member Functions inherited from CellMLToNektar.pycml.element_base
def __delattr__ (self, key)
 
def __setattr__ (self, key, value)
 
def rootNode (self)
 
def cmeta_id (self)
 
def xml_remove_child_at (self, index=-1)
 
def xml_doc (self)
 
def xml_properties (self)
 

Static Public Attributes

string math_xpath_1 = u'cml:component/m:math'
 
string math_xpath_2 = u'cml:component/cml:reaction/cml:variable_ref/cml:role/m:math'
 
string apply_xpath_1 = u'/m:apply[m:eq]'
 
string apply_xpath_2 = u'/m:semantics/m:apply[m:eq]'
 

Private Member Functions

def _add_variable (self, var, varname, compname)
 
def _del_variable (self, varname, compname)
 
def _add_component (self, comp, special=False)
 
def _del_component (self, comp)
 
def _report_exception (self, e, show_xml_context)
 
def _validate_component_hierarchies (self)
 
def _check_variable_mappings (self)
 
def _validate_connection (self, conn)
 
def _check_variable_units_exist (self)
 
def _check_connection_units (self, check_for_units_conversions=False)
 
def _check_maths_name_references (self, expr, xml_context=False)
 
def _check_assigned_vars (self, assignments, xml_context=False)
 
def _check_cellml_subset (self, math_elts, root=True)
 
def _classify_variables (self, assignment_exprs, xml_context=False)
 
def _order_variables (self, assignment_exprs, xml_context=False)
 
def _add_sorted_assignment (self, a)
 
def _remove_assignment (self, a)
 
def _check_dimensional_consistency (self, assignment_exprs, xml_context=False, warn_on_units_errors=False, check_for_units_conversions=False)
 
def _check_unit_cycles (self, unit)
 
def _build_units_dictionary (self)
 
def _add_units_obj (self, units)
 
def _get_units_obj (self, units)
 
def _is_new_units_obj (self, units)
 

Private Attributes

 _cml_validation_errors
 
 _cml_validation_warnings
 
 _cml_variables
 
 _cml_components
 
 _cml_units
 
 _cml_standard_units
 
 _cml_units_map
 
 _cml_assignments
 
 _cml_sorting_variables_stack
 
 _cml_conversions_needed
 

Additional Inherited Members

- Public Attributes inherited from CellMLToNektar.pycml.element_base
 xml_attributes
 

Detailed Description

Specialised class for the model element of a CellML document.
Adds methods for collecting and reporting validation errors, etc.

Definition at line 377 of file pycml.py.

Constructor & Destructor Documentation

◆ __init__()

def CellMLToNektar.pycml.cellml_model.__init__ (   self)

Reimplemented from CellMLToNektar.pycml.element_base.

Definition at line 383 of file pycml.py.

383  def __init__(self):
384  element_base.__init__(self)
385  self._cml_validation_errors = []
386  self._cml_validation_warnings = []
387  self._cml_variables = {}
388  self._cml_components = {}
389  self._cml_units = {}
390  self._cml_standard_units = {}
391  self._cml_units_map = {}
392  # Topologically sorted assignments list
393  self._cml_assignments = []
394 

◆ __del__()

def CellMLToNektar.pycml.cellml_model.__del__ (   self)

Definition at line 395 of file pycml.py.

395  def __del__(self):
396  self.clean_up()
397 

References CellMLToNektar.pycml.cellml_model.clean_up().

Member Function Documentation

◆ _add_component()

def CellMLToNektar.pycml.cellml_model._add_component (   self,
  comp,
  special = False 
)
private
Add a new component to the model.

Definition at line 499 of file pycml.py.

499  def _add_component(self, comp, special=False):
500  """Add a new component to the model."""
501  if special:
502  comp.xml_parent = self
503  else:
504  self.xml_append(comp)
505  self._cml_components[comp.name] = comp
506 

References CellMLToNektar.pycml.cellml_model._cml_components.

◆ _add_sorted_assignment()

def CellMLToNektar.pycml.cellml_model._add_sorted_assignment (   self,
  a 
)
private
During the topological sort, add a finished assignment to the
list.  This list can then be executed in order to simulate the
model.

The element added can either be a MathML expression
representing an assignment, or a CellML variable element,
indicating an assignment due to a variable mapping.

Definition at line 1095 of file pycml.py.

1095  def _add_sorted_assignment(self, a):
1096  """
1097  During the topological sort, add a finished assignment to the
1098  list. This list can then be executed in order to simulate the
1099  model.
1100 
1101  The element added can either be a MathML expression
1102  representing an assignment, or a CellML variable element,
1103  indicating an assignment due to a variable mapping.
1104  """
1105  self._cml_assignments.append(a)

References CellMLToNektar.pycml.cellml_model._cml_assignments.

Referenced by CellMLToNektar.pycml.cellml_model.topological_sort().

◆ _add_units_obj()

def CellMLToNektar.pycml.cellml_model._add_units_obj (   self,
  units 
)
private
Add a units object into the global hashmap.

Definition at line 1331 of file pycml.py.

1331  def _add_units_obj(self, units):
1332  """Add a units object into the global hashmap."""
1333  if not units.uniquify_tuple in self._cml_units_map:
1334  self._cml_units_map[units.uniquify_tuple] = units
1335  return
1336 

References CellMLToNektar.pycml.cellml_model._cml_units_map.

Referenced by CellMLToNektar.pycml.cellml_model._build_units_dictionary(), and CellMLToNektar.pycml.cellml_model.add_units().

◆ _add_variable()

def CellMLToNektar.pycml.cellml_model._add_variable (   self,
  var,
  varname,
  compname 
)
private
Add a new variable to the model.

Definition at line 490 of file pycml.py.

490  def _add_variable(self, var, varname, compname):
491  """Add a new variable to the model."""
492  assert (compname, varname) not in self._cml_variables
493  self._cml_variables[(compname, varname)] = var
494 

References CellMLToNektar.pycml.cellml_model._cml_variables.

◆ _build_units_dictionary()

def CellMLToNektar.pycml.cellml_model._build_units_dictionary (   self)
private
Create a dictionary mapping units names to objects, for all units definitions in this element.

Definition at line 1210 of file pycml.py.

1210  def _build_units_dictionary(self):
1211  """Create a dictionary mapping units names to objects, for all units definitions in this element."""
1212  # Standard units
1213  std_units = self._cml_standard_units
1214  def make(name, bases):
1215  return cellml_units.create_new(self, name, bases, standard=True)
1216  # SI base units & dimensionless
1217  base_units = [u'ampere', u'candela', u'dimensionless', u'kelvin',
1218  u'kilogram', u'metre', u'mole', u'second']
1219  base_units.append(u'#FUDGE#') # Used for PE of naughty models
1220  for units in base_units:
1221  std_units[units] = make(units, [])
1222  # Special cellml:boolean units
1223  boolean = make(u'cellml:boolean', [])
1224  std_units[u'cellml:boolean'] = boolean
1225  # Convenience derived units
1226  gram = make('gram', [{'units': 'kilogram', 'multiplier': '0.001'}])
1227  litre = make('litre', [{'multiplier': '1000', 'prefix': 'centi',
1228  'units': 'metre', 'exponent': '3'}])
1229  # SI derived units
1230  radian = make('radian', [{'units': 'metre'},
1231  {'units': 'metre', 'exponent': '-1'}])
1232  steradian = make('steradian', [{'units': 'metre', 'exponent': '2'},
1233  {'units': 'metre', 'exponent': '-2'}])
1234  hertz = make('hertz', [{'units': 'second', 'exponent': '-1'}])
1235  newton = make('newton', [{'units': 'metre'},
1236  {'units': 'kilogram'},
1237  {'units': 'second', 'exponent': '-2'}])
1238  pascal = make('pascal', [{'units': 'newton'},
1239  {'units': 'metre', 'exponent': '-2'}])
1240  joule = make('joule', [{'units': 'newton'},
1241  {'units': 'metre'}])
1242  watt = make('watt', [{'units': 'joule'},
1243  {'units': 'second', 'exponent': '-1'}])
1244  coulomb = make('coulomb', [{'units': 'second'},
1245  {'units': 'ampere'}])
1246  volt = make('volt', [{'units': 'watt'},
1247  {'units': 'ampere', 'exponent': '-1'}])
1248  farad = make('farad', [{'units': 'coulomb'},
1249  {'units': 'volt', 'exponent': '-1'}])
1250  ohm = make('ohm', [{'units': 'volt'},
1251  {'units': 'ampere', 'exponent': '-1'}])
1252  siemens = make('siemens', [{'units': 'ampere'},
1253  {'units': 'volt', 'exponent': '-1'}])
1254  weber = make('weber', [{'units': 'volt'},
1255  {'units': 'second'}])
1256  tesla = make('tesla', [{'units': 'weber'},
1257  {'units': 'metre', 'exponent': '-2'}])
1258  henry = make('henry', [{'units': 'weber'},
1259  {'units': 'ampere', 'exponent': '-1'}])
1260  celsius = make('celsius', [{'units': 'kelvin', 'offset': '-273.15'}])
1261  lumen = make('lumen', [{'units': 'candela'},
1262  {'units': 'steradian'}])
1263  lux = make('lux', [{'units': 'lumen'},
1264  {'units': 'metre', 'exponent': '-2'}])
1265  becquerel = make('becquerel', [{'units': 'second', 'exponent': '-1'}])
1266  gray = make('gray', [{'units': 'joule'},
1267  {'units': 'kilogram', 'exponent': '-1'}])
1268  sievert = make('sievert', [{'units': 'joule'},
1269  {'units': 'kilogram', 'exponent': '-1'}])
1270  katal = make('katal', [{'units': 'second', 'exponent': '-1'},
1271  {'units': 'mole'}])
1272  for units in [becquerel, celsius, coulomb, farad, gram, gray, henry,
1273  hertz, joule, katal, litre, lumen, lux, newton, ohm,
1274  pascal, radian, siemens, sievert, steradian, tesla,
1275  volt, watt, weber]:
1276  std_units[units.name] = units
1277  # American spellings
1278  std_units[u'meter'] = std_units[u'metre']
1279  std_units[u'liter'] = std_units[u'litre']
1280  # User-defined units
1281  model_units = self._cml_units
1282  model_units.update(std_units)
1283  if hasattr(self, u'units'):
1284  for units in self.units:
1285  if units.name in model_units:
1286  self.validation_error("Units names must be unique within the parent component or model,"
1287  " and must not redefine the standard units (5.4.1.2)."
1288  " The units definition named '%s' in the model is a duplicate." % units.name)
1289  model_units[units.name] = units
1290  # Update units hashmap
1291  for u in model_units.itervalues():
1292  self._add_units_obj(u)
1293 

References CellMLToNektar.pycml.cellml_model._add_units_obj(), CellMLToNektar.pycml.cellml_model._cml_standard_units, CellMLToNektar.pycml.cellml_model._cml_units, CellMLToNektar.pycml.cellml_component._cml_units, CellMLToNektar.pycml.mathml_units_mixin_tokens._cml_units, CellMLToNektar.pycml.mathml_units_mixin_container._cml_units, CellMLToNektar.pycml.mathml_cn._cml_units, CellMLToNektar.pycml.mathml_ci._cml_units, CellMLToNektar.pycml.mathml_apply._cml_units, CellMLToNektar.pycml.mathml_piecewise._cml_units, and CellMLToNektar.pycml.cellml_model.validation_error().

Referenced by CellMLToNektar.pycml.cellml_model.add_units(), CellMLToNektar.pycml.cellml_component.add_units(), CellMLToNektar.pycml.cellml_model.get_all_units(), CellMLToNektar.pycml.cellml_component.get_all_units(), CellMLToNektar.pycml.cellml_model.get_standard_units(), CellMLToNektar.pycml.cellml_model.get_units_by_name(), and CellMLToNektar.pycml.cellml_component.get_units_by_name().

◆ _check_assigned_vars()

def CellMLToNektar.pycml.cellml_model._check_assigned_vars (   self,
  assignments,
  xml_context = False 
)
private
Check Rule 4.4.4: mathematical expressions may only modify
variables belonging to the current component.

Definition at line 842 of file pycml.py.

842  def _check_assigned_vars(self, assignments, xml_context=False):
843  """Check Rule 4.4.4: mathematical expressions may only modify
844  variables belonging to the current component.
845  """
846  for expr in assignments:
847  try:
848  expr.check_assigned_var()
849  except MathsError, e:
850  self._report_exception(e, xml_context)
851  DEBUG('validator', 'Checked variable assignments')
852 
def DEBUG(facility, *args)
Definition: utilities.py:95

References CellMLToNektar.pycml.cellml_model._report_exception(), and CellMLToNektar.utilities.DEBUG().

Referenced by CellMLToNektar.pycml.cellml_model.validate().

◆ _check_cellml_subset()

def CellMLToNektar.pycml.cellml_model._check_cellml_subset (   self,
  math_elts,
  root = True 
)
private
Warn if MathML outside the CellML subset is used.

Definition at line 853 of file pycml.py.

853  def _check_cellml_subset(self, math_elts, root=True):
854  """Warn if MathML outside the CellML subset is used."""
855  for elt in math_elts:
856  if not elt.localName in CELLML_SUBSET_ELTS and \
857  elt.namespaceURI == NSS[u'm']:
858  self.validation_warning(u' '.join([
859  u'MathML element', elt.localName,
860  u'is not in the CellML subset.',
861  u'Some tools may not be able to process it.']))
862  self._check_cellml_subset(self.xml_element_children(elt), False)
863  if root:
864  DEBUG('validator', 'Checked for CellML subset')
865 

References CellMLToNektar.pycml.cellml_model._check_cellml_subset(), CellMLToNektar.utilities.DEBUG(), and CellMLToNektar.pycml.cellml_model.validation_warning().

Referenced by CellMLToNektar.pycml.cellml_model._check_cellml_subset(), and CellMLToNektar.pycml.cellml_model.validate().

◆ _check_connection_units()

def CellMLToNektar.pycml.cellml_model._check_connection_units (   self,
  check_for_units_conversions = False 
)
private
Check that the units of mapped variables are dimensionally consistent.

If check_for_units_conversions is True we also warn if they are not equivalent,
since much processing software may not be able to handle that case.

Definition at line 786 of file pycml.py.

786  def _check_connection_units(self, check_for_units_conversions=False):
787  """Check that the units of mapped variables are dimensionally consistent.
788 
789  If check_for_units_conversions is True we also warn if they are not equivalent,
790  since much processing software may not be able to handle that case.
791  """
792  for conn in getattr(self, u'connection', []):
793  comp1 = self.get_component_by_name(conn.map_components.component_1)
794  comp2 = self.get_component_by_name(conn.map_components.component_2)
795  for mapping in conn.map_variables:
796  var1 = self.get_variable_by_name(comp1.name, mapping.variable_1)
797  var2 = self.get_variable_by_name(comp2.name, mapping.variable_2)
798  # Check the units
799  u1 = var1.get_units()
800  u2 = var2.get_units()
801  if not u1 == u2:
802  if not u1.dimensionally_equivalent(u2):
803  self.validation_error(u' '.join([
804  var1.fullname(), 'and', var2.fullname(),
805  'are mapped, but have dimensionally inconsistent units.']))
806  elif check_for_units_conversions:
807  self.validation_warning(
808  u' '.join(['Warning: mapping between', var1.fullname(), 'and',
809  var2.fullname(), 'will require a units conversion.']),
810  level=logging.WARNING_TRANSLATE_ERROR)
811 

References CellMLToNektar.pycml.cellml_model.get_component_by_name(), CellMLToNektar.pycml.cellml_model.get_variable_by_name(), CellMLToNektar.pycml.cellml_component.get_variable_by_name(), CellMLToNektar.pycml.cellml_model.validation_error(), and CellMLToNektar.pycml.cellml_model.validation_warning().

Referenced by CellMLToNektar.pycml.cellml_model.validate().

◆ _check_dimensional_consistency()

def CellMLToNektar.pycml.cellml_model._check_dimensional_consistency (   self,
  assignment_exprs,
  xml_context = False,
  warn_on_units_errors = False,
  check_for_units_conversions = False 
)
private
Appendix C.3.6: Equation dimension checking.

Definition at line 1151 of file pycml.py.

1154  check_for_units_conversions=False):
1155  """Appendix C.3.6: Equation dimension checking."""
1156  self._cml_conversions_needed = False
1157  # Check dimensions
1158  for expr in assignment_exprs:
1159  try:
1160  expr.get_units()
1161  except UnitsError, e:
1162  if warn_on_units_errors:
1163  e.warn = True
1164  e.level = logging.WARNING
1165  self._report_exception(e, xml_context)
1166  # Check if units conversions will be needed
1167  if check_for_units_conversions and not self._cml_validation_errors:
1168  boolean = self.get_units_by_name('cellml:boolean')
1169  for expr in assignment_exprs:
1170  try:
1171  DEBUG('validator', "Checking units in", element_xpath(expr), expr.component.name)
1172  expr._set_in_units(boolean, no_act=True)
1173  except UnitsError:
1174  pass
1175  # Warn if conversions used
1176  if self._cml_conversions_needed:
1177  self.validation_warning('The mathematics in this model require units conversions.',
1178  level=logging.WARNING)
1179  DEBUG('validator', 'Checked units')
1180 

Referenced by CellMLToNektar.pycml.cellml_model.validate().

◆ _check_maths_name_references()

def CellMLToNektar.pycml.cellml_model._check_maths_name_references (   self,
  expr,
  xml_context = False 
)
private
Check rules 4.4.2.1 and 4.4.3.2: name references in mathematics.

Definition at line 812 of file pycml.py.

812  def _check_maths_name_references(self, expr, xml_context=False):
813  """Check rules 4.4.2.1 and 4.4.3.2: name references in mathematics."""
814  if isinstance(expr, mathml_ci):
815  # Check variable exists
816  try:
817  _ = expr.variable
818  except KeyError:
819  self._report_exception(
820  MathsError(expr,
821  "The content of a MathML ci element must match the name of a variable "
822  "in the enclosing component, once whitespace normalisation has been "
823  "performed (4.4.2.1). Variable '%s' does not exist in component '%s'."
824  % (unicode(expr).strip(), expr.component.name)),
825  xml_context)
826  elif isinstance(expr, mathml_cn):
827  # Check units exist
828  try:
829  expr.get_units()
830  except KeyError:
831  self._report_exception(
832  MathsError(expr,
833  "Units on a cn element must be standard or defined in the current "
834  "component or model (4.4.3.2). Units '%s' are not defined in "
835  "component '%s'." % (expr.units, expr.component.name)),
836  xml_context)
837  else:
838  # Recurse
839  for child in expr.xml_element_children():
840  self._check_maths_name_references(child, xml_context)
841 

References CellMLToNektar.pycml.cellml_model._check_maths_name_references(), and CellMLToNektar.pycml.cellml_model._report_exception().

Referenced by CellMLToNektar.pycml.cellml_model._check_maths_name_references(), and CellMLToNektar.pycml.cellml_model.validate().

◆ _check_unit_cycles()

def CellMLToNektar.pycml.cellml_model._check_unit_cycles (   self,
  unit 
)
private
Check for cyclic units definitions.

We do this by doing a depth-first search from unit.

Definition at line 1181 of file pycml.py.

1181  def _check_unit_cycles(self, unit):
1182  """Check for cyclic units definitions.
1183 
1184  We do this by doing a depth-first search from unit.
1185  """
1186  if unit.get_colour() != DFS.White:
1187  # Allow self.validate to call us without colour check
1188  return
1189  unit.set_colour(DFS.Gray)
1190  # Get the object unit is defined in
1191  parent = unit.xml_parent or self
1192  for u in getattr(unit, u'unit', []):
1193  # Explore units that this unit is defined in terms of
1194  try:
1195  v = parent.get_units_by_name(u.units)
1196  except KeyError:
1197  self.validation_error("The value of the units attribute on a unit element must be taken"
1198  " from the dictionary of standard units or be the name of a"
1199  " user-defined unit in the current component or model (5.4.2.2)."
1200  " Units '%s' are not defined." % u.units)
1201  continue
1202  if v.get_colour() == DFS.White:
1203  self._check_unit_cycles(v)
1204  elif v.get_colour() == DFS.Gray:
1205  # We have a cycle
1206  self.validation_error("Units %s and %s are in a cyclic units definition"
1207  % (unit.name, v.name))
1208  unit.set_colour(DFS.Black)
1209 

References CellMLToNektar.pycml.cellml_model._check_unit_cycles(), and CellMLToNektar.pycml.cellml_model.validation_error().

Referenced by CellMLToNektar.pycml.cellml_model._check_unit_cycles(), and CellMLToNektar.pycml.cellml_model.validate().

◆ _check_variable_mappings()

def CellMLToNektar.pycml.cellml_model._check_variable_mappings (   self)
private
Check Rules 3.4.{5,6}: check variable mappings and interfaces are sane.

Definition at line 663 of file pycml.py.

663  def _check_variable_mappings(self):
664  """Check Rules 3.4.{5,6}: check variable mappings and interfaces are sane."""
665  # First check connection elements and build mappings dict
666  self.build_name_dictionaries()
667  connected_components = set()
668  for connection in getattr(self, u'connection', []):
669  comps = frozenset([connection.map_components.component_1, connection.map_components.component_2])
670  if comps in connected_components:
671  self.validation_error("Each map_components element must map a unique pair of components "
672  "(3.4.5.4). The pair ('%s', '%s') is repeated." % tuple(comps))
673  connected_components.add(comps)
674  self._validate_connection(connection)
675  # Now check for variables that should receive a value but don't
676  for comp in getattr(self, u'component', []):
677  for var in getattr(comp, u'variable', []):
678  for iface in [u'private_interface', u'public_interface']:
679  if getattr(var, iface, u'none') == u'in':
680  try:
681  var.get_source_variable()
682  except TypeError:
683  # No source variable found
684  self.validation_error("Variable '%s' has a %s attribute with value 'in', "
685  "but no component exports a value to that variable."
686  % (var.fullname(), iface))
687  DEBUG('validator', 'Checked variable mappings')
688 

References CellMLToNektar.pycml.cellml_model._validate_connection(), CellMLToNektar.pycml.cellml_model.build_name_dictionaries(), CellMLToNektar.utilities.DEBUG(), and CellMLToNektar.pycml.cellml_model.validation_error().

Referenced by CellMLToNektar.pycml.cellml_model.validate().

◆ _check_variable_units_exist()

def CellMLToNektar.pycml.cellml_model._check_variable_units_exist (   self)
private
Check rule 3.4.3.3: that the units declared for variables exist.

Definition at line 774 of file pycml.py.

774  def _check_variable_units_exist(self):
775  """Check rule 3.4.3.3: that the units declared for variables exist."""
776  for var in self.get_all_variables():
777  try:
778  var.get_units()
779  except KeyError:
780  self.validation_error("The value of the units attribute on a variable must be either "
781  "one of the standard units or the name of a unit defined in the "
782  "current component or model (3.4.3.3). The units '%s' on the "
783  "variable '%s' in component '%s' do not exist."
784  % (var.units, var.name, var.component.name))
785 

References CellMLToNektar.pycml.cellml_model.get_all_variables(), and CellMLToNektar.pycml.cellml_model.validation_error().

Referenced by CellMLToNektar.pycml.cellml_model.validate().

◆ _classify_variables()

def CellMLToNektar.pycml.cellml_model._classify_variables (   self,
  assignment_exprs,
  xml_context = False 
)
private
Determine the type of each variable.

Note that mapped vars must have already been classified by
self._check_variable_mappings, and the RELAX NG schema ensures
that a variable cannot be both Mapped and MaybeConstant.

Builds the equation dependency graph in the process.

Definition at line 866 of file pycml.py.

866  def _classify_variables(self, assignment_exprs, xml_context=False):
867  """Determine the type of each variable.
868 
869  Note that mapped vars must have already been classified by
870  self._check_variable_mappings, and the RELAX NG schema ensures
871  that a variable cannot be both Mapped and MaybeConstant.
872 
873  Builds the equation dependency graph in the process.
874  """
875  # Classify those vars that might be constants,
876  # i.e. have an initial value assigned.
877  for var in self.get_all_variables():
878  if hasattr(var, u'initial_value'):
879  var._set_type(VarTypes.MaybeConstant)
880  # Now classify by checking usage in mathematics, building
881  # an equation dependency graph in the process.
882  for expr in assignment_exprs:
883  try:
884  expr.classify_variables(root=True)
885  except MathsError, e:
886  self._report_exception(e, xml_context)
887  # Unused vars still classified as MaybeConstant are constants
888  for var in self.get_all_variables():
889  if var.get_type() == VarTypes.MaybeConstant:
890  var._set_type(VarTypes.Constant)
891  DEBUG('validator', 'Classified variables')
892 

References CellMLToNektar.pycml.cellml_model._report_exception(), CellMLToNektar.utilities.DEBUG(), and CellMLToNektar.pycml.cellml_model.get_all_variables().

Referenced by CellMLToNektar.pycml.cellml_model.validate().

◆ _del_component()

def CellMLToNektar.pycml.cellml_model._del_component (   self,
  comp 
)
private
Remove the given component from the model.

Definition at line 507 of file pycml.py.

507  def _del_component(self, comp):
508  """Remove the given component from the model."""
509  self.xml_remove_child(comp)
510  del self._cml_components[comp.name]
511 

References CellMLToNektar.pycml.cellml_model._cml_components.

◆ _del_variable()

def CellMLToNektar.pycml.cellml_model._del_variable (   self,
  varname,
  compname 
)
private
Remove a variable from the model.

Definition at line 495 of file pycml.py.

495  def _del_variable(self, varname, compname):
496  """Remove a variable from the model."""
497  del self._cml_variables[(compname, varname)]
498 

References CellMLToNektar.pycml.cellml_model._cml_variables.

◆ _get_units_obj()

def CellMLToNektar.pycml.cellml_model._get_units_obj (   self,
  units 
)
private
Unique-ify this units object.

If an object with the same definition already exists, return that.
Otherwise return the given units object.

'Same definition' is based on the cellml_units.uniquify_tuple
property, which in turn is based partly on the generated name
which would be given to these units, since that really *must*
be unique in generated models.

Definition at line 1337 of file pycml.py.

1337  def _get_units_obj(self, units):
1338  """Unique-ify this units object.
1339 
1340  If an object with the same definition already exists, return that.
1341  Otherwise return the given units object.
1342 
1343  'Same definition' is based on the cellml_units.uniquify_tuple
1344  property, which in turn is based partly on the generated name
1345  which would be given to these units, since that really *must*
1346  be unique in generated models.
1347  """
1348  return self._cml_units_map.get(units.uniquify_tuple, units)
1349 

References CellMLToNektar.pycml.cellml_model._cml_units_map.

◆ _is_new_units_obj()

def CellMLToNektar.pycml.cellml_model._is_new_units_obj (   self,
  units 
)
private
Have these units been generated already?

i.e. is a units object with this definition in our map?

Definition at line 1350 of file pycml.py.

1350  def _is_new_units_obj(self, units):
1351  """Have these units been generated already?
1352 
1353  i.e. is a units object with this definition in our map?
1354  """
1355  return units.uniquify_tuple not in self._cml_units_map
1356 

References CellMLToNektar.pycml.cellml_model._cml_units_map.

◆ _order_variables()

def CellMLToNektar.pycml.cellml_model._order_variables (   self,
  assignment_exprs,
  xml_context = False 
)
private
Topologically sort the equation dependency graph.

This orders all the assignment expressions in the model, to
allow procedural code generation.  It also checks that equations
are not cyclic (we don't support DAEs).

Definition at line 893 of file pycml.py.

893  def _order_variables(self, assignment_exprs, xml_context=False):
894  """Topologically sort the equation dependency graph.
895 
896  This orders all the assignment expressions in the model, to
897  allow procedural code generation. It also checks that equations
898  are not cyclic (we don't support DAEs).
899  """
900  self.clear_assignments() # Ensure we start from a clean slate
901  try:
902  self._cml_sorting_variables_stack = []
903  for var in self.get_all_variables():
904  if var.get_colour() == DFS.White:
905  self.topological_sort(var)
906  for expr in assignment_exprs:
907  if expr.get_colour() == DFS.White:
908  self.topological_sort(expr)
909  except MathsError, e:
910  self._report_exception(e, xml_context)
911  DEBUG('validator', 'Topologically sorted variables')
912 

References CellMLToNektar.pycml.cellml_model.clear_assignments().

Referenced by CellMLToNektar.pycml.cellml_model.validate().

◆ _remove_assignment()

def CellMLToNektar.pycml.cellml_model._remove_assignment (   self,
  a 
)
private
Remove the given assignment from our list.

This method is used by the partial evaluator.

Definition at line 1106 of file pycml.py.

1106  def _remove_assignment(self, a):
1107  """Remove the given assignment from our list.
1108 
1109  This method is used by the partial evaluator."""
1110  self._cml_assignments.remove(a)

References CellMLToNektar.pycml.cellml_model._cml_assignments.

◆ _report_exception()

def CellMLToNektar.pycml.cellml_model._report_exception (   self,
  e,
  show_xml_context 
)
private
Report an exception e as a validation error or warning.

If show_xml_context is True, display the XML of the context
of the exception as well.

Definition at line 533 of file pycml.py.

533  def _report_exception(self, e, show_xml_context):
534  """Report an exception e as a validation error or warning.
535 
536  If show_xml_context is True, display the XML of the context
537  of the exception as well.
538  """
539  e.show_xml_context = show_xml_context
540  if e.warn:
541  self.validation_warning(unicode(e), level=e.level)
542  else:
543  self.validation_error(unicode(e), level=e.level)
544 

References CellMLToNektar.pycml.cellml_model.validation_error(), and CellMLToNektar.pycml.cellml_model.validation_warning().

Referenced by CellMLToNektar.pycml.cellml_model._check_assigned_vars(), CellMLToNektar.pycml.cellml_model._check_maths_name_references(), and CellMLToNektar.pycml.cellml_model._classify_variables().

◆ _validate_component_hierarchies()

def CellMLToNektar.pycml.cellml_model._validate_component_hierarchies (   self)
private
Check Rule 6.4.3.2 (4): hierarchies must not be circular.

Builds all the hierarchies, and checks for cycles.
In the process, we also check the other rules in 6.4.3, and 6.4.2.5.

Definition at line 632 of file pycml.py.

632  def _validate_component_hierarchies(self):
633  """Check Rule 6.4.3.2 (4): hierarchies must not be circular.
634 
635  Builds all the hierarchies, and checks for cycles.
636  In the process, we also check the other rules in 6.4.3, and 6.4.2.5.
637  """
638  # First, we find the hierarchies that are defined.
639  hiers = set()
640  rels = []
641  for group in getattr(self, u'group', []):
642  local_hiers = set()
643  for rel in getattr(group, u'relationship_ref', []):
644  rels.append(rel)
645  reln = rel.relationship
646  ns = rel.xml_attributes[u'relationship'][1]
647  name = getattr(rel, u'name', None)
648  hier = (reln, ns, name)
649  if hier in local_hiers:
650  self.validation_error("A group element must not contain two or more relationship_ref"
651  " elements that define a relationship attribute in a common"
652  " namespace with the same value and that have the same name"
653  " attribute value (which may be non-existent) (6.4.2.5)."
654  " Relationship '%s' name '%s' in namespace '%s' is repeated."
655  % (reln, name or '', ns))
656  local_hiers.add(hier)
657  hiers.add(hier)
658  # Now build & check each hierarchy
659  for hier in hiers:
660  self.build_component_hierarchy(hier[0], hier[1], hier[2], rels=rels)
661  DEBUG('validator', 'Checked component hierachies')
662 

References CellMLToNektar.pycml.cellml_model.build_component_hierarchy(), CellMLToNektar.utilities.DEBUG(), and CellMLToNektar.pycml.cellml_model.validation_error().

Referenced by CellMLToNektar.pycml.cellml_model.validate().

◆ _validate_connection()

def CellMLToNektar.pycml.cellml_model._validate_connection (   self,
  conn 
)
private
Validate the given connection element.

Check that the given connection object defines valid mappings
between variables, according to rules 3.4.5 and 3.4.6.

Definition at line 689 of file pycml.py.

689  def _validate_connection(self, conn):
690  """Validate the given connection element.
691 
692  Check that the given connection object defines valid mappings
693  between variables, according to rules 3.4.5 and 3.4.6.
694  """
695  # Check we are allowed to connect these components
696  try:
697  comp1 = self.get_component_by_name(conn.map_components.component_1)
698  except KeyError:
699  self.validation_error("Connections must be between components defined in the current model "
700  "(3.4.5.2). There is no component '%s'." % conn.map_components.component_1)
701  return
702  try:
703  comp2 = self.get_component_by_name(conn.map_components.component_2)
704  except KeyError:
705  self.validation_error("Connections must be between components defined in the current model "
706  "(3.4.5.3). There is no component '%s'." % conn.map_components.component_2)
707  return
708  if comp1 is comp2:
709  self.validation_error("A connection must link two different components (3.4.5.4). "
710  "The component '%s' is being connected to itself." % comp1.name)
711  return
712  # Get the parent of each component in the encapsulation hierarchy
713  par1, par2 = comp1.parent(), comp2.parent()
714  # The two components must either be siblings (maybe top-level) or parent & child.
715  if not (par1 == comp2 or par2 == comp1 or par1 == par2):
716  self.validation_error(u' '.join([
717  'Connections are only permissible between sibling',
718  'components, or where one is the parent of the other.\n',
719  comp1.name,'and',comp2.name,'are unrelated.']))
720  return
721  # Now check each variable mapping
722  for mapping in conn.map_variables:
723  try:
724  var1 = self.get_variable_by_name(comp1.name, mapping.variable_1)
725  except KeyError:
726  self.validation_error("A variable mapping must be between existing variables (3.4.6.2). "
727  "Variable '%s' doesn't exist in component '%s'."
728  % (mapping.variable_1, comp1.name))
729  continue
730  try:
731  var2 = self.get_variable_by_name(comp2.name, mapping.variable_2)
732  except KeyError:
733  self.validation_error("A variable mapping must be between existing variables (3.4.6.2). "
734  "Variable '%s' doesn't exist in component '%s'."
735  % (mapping.variable_2, comp2.name))
736  continue
737  errm, e = ['Interface mismatch mapping',var1.fullname(),'and',var2.fullname(),':\n'], None
738  if par1 == par2:
739  # Siblings, so should have differing public interfaces
740  if not hasattr(var1, 'public_interface'):
741  e = 'missing public_interface attribute on ' + \
742  var1.fullname() + '.'
743  elif not hasattr(var2, 'public_interface'):
744  e = 'missing public_interface attribute on ' + \
745  var2.fullname() + '.'
746  elif var1.public_interface == var2.public_interface:
747  e = 'public_interface attributes are identical.'
748  else:
749  if var1.public_interface == 'in':
750  var1._set_source_variable(var2)
751  else:
752  var2._set_source_variable(var1)
753  else:
754  if par2 == comp1:
755  # Component 1 is the parent of component 2
756  var1, var2 = var2, var1
757  # Now var2 is in the parent component, and var1 in the child
758  if not hasattr(var1, 'public_interface'):
759  e = var1.fullname()+' missing public_interface.'
760  elif not hasattr(var2, 'private_interface'):
761  e = var2.fullname()+' missing private_interface.'
762  elif var1.public_interface == var2.private_interface:
763  e = 'relevant interfaces have identical values.'
764  else:
765  if var1.public_interface == 'in':
766  var1._set_source_variable(var2)
767  else:
768  var2._set_source_variable(var1)
769  # If there was an error, log it
770  if e:
771  errm.append(e)
772  self.validation_error(u' '.join(errm))
773 

References CellMLToNektar.pycml.cellml_model.get_component_by_name(), CellMLToNektar.pycml.cellml_model.get_variable_by_name(), CellMLToNektar.pycml.cellml_component.get_variable_by_name(), and CellMLToNektar.pycml.cellml_model.validation_error().

Referenced by CellMLToNektar.pycml.cellml_model._check_variable_mappings().

◆ add_units()

def CellMLToNektar.pycml.cellml_model.add_units (   self,
  name,
  units 
)
Add an entry in our units dictionary for units named `name' with element object `units'.

Definition at line 1318 of file pycml.py.

1318  def add_units(self, name, units):
1319  """Add an entry in our units dictionary for units named `name' with element object `units'."""
1320  if not self._cml_units:
1321  self._build_units_dictionary()
1322  assert name not in self._cml_units
1323  self._cml_units[name] = units
1324  self._add_units_obj(units)
1325  return
1326 

References CellMLToNektar.pycml.cellml_model._add_units_obj(), CellMLToNektar.pycml.cellml_model._build_units_dictionary(), CellMLToNektar.pycml.cellml_component._build_units_dictionary(), CellMLToNektar.pycml.cellml_model._cml_units, CellMLToNektar.pycml.cellml_component._cml_units, CellMLToNektar.pycml.mathml_units_mixin_tokens._cml_units, CellMLToNektar.pycml.mathml_units_mixin_container._cml_units, CellMLToNektar.pycml.mathml_cn._cml_units, CellMLToNektar.pycml.mathml_ci._cml_units, CellMLToNektar.pycml.mathml_apply._cml_units, and CellMLToNektar.pycml.mathml_piecewise._cml_units.

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

◆ add_units_conversions()

def CellMLToNektar.pycml.cellml_model.add_units_conversions (   self)
Add explicit units conversion mathematics where necessary.

Definition at line 1357 of file pycml.py.

1357  def add_units_conversions(self):
1358  """Add explicit units conversion mathematics where necessary."""
1360  processors.UnitsConverter(self).add_all_conversions()
1361 
def import_processors()
Definition: pycml.py:84

References CellMLToNektar.pycml.import_processors().

◆ build_component_hierarchy()

def CellMLToNektar.pycml.cellml_model.build_component_hierarchy (   self,
  relationship,
  namespace = None,
  name = None,
  rels = None 
)
Create all the parent-child links for the given component hierarchy.

relationship gives the type of the hierarchy. If it is not one of the
CellML types (i.e. encapsulation or containment) then the namespace URI
must be specified.  Multiple non-encapsulation hierarchies of the same
type can be specified by giving the name argument.

Definition at line 958 of file pycml.py.

958  def build_component_hierarchy(self, relationship, namespace=None, name=None, rels=None):
959  """
960  Create all the parent-child links for the given component hierarchy.
961 
962  relationship gives the type of the hierarchy. If it is not one of the
963  CellML types (i.e. encapsulation or containment) then the namespace URI
964  must be specified. Multiple non-encapsulation hierarchies of the same
965  type can be specified by giving the name argument.
966  """
967  key = (relationship, namespace, name)
968  # Set all components to have no parent or children, under this hierarchy
969  for comp in getattr(self, u'component', []):
970  comp._clear_hierarchy(key)
971  self.build_name_dictionaries()
972  # Find nodes defining this hierarchy
973  if rels is None:
974  rels = self.xml_xpath(u'cml:group/cml:relationship_ref')
975  groups = []
976  for rel in rels:
977  # NB: The first test below relies on there only being one
978  # attr with localname of 'relationship' on each rel.
979  # So let's check this...
980  if hasattr(rel, u'relationship_'):
981  self.validation_error(u' '.join([
982  'relationship_ref element has multiple relationship',
983  'attributes in different namespaces:\n'] +
984  map(lambda qn,ns: '('+qn+','+ns+')',
985  rel.xml_attributes.values())))
986  return
987  if rel.relationship == relationship and \
988  rel.xml_attributes[u'relationship'][1] == namespace and \
989  getattr(rel, u'name', None) == name:
990  # It's in the hierarchy
991  groups.append(rel.xml_parent)
992  # Now build all the parent links for this hierarchy
993  def set_parent(p, crefs):
994  for cref in crefs:
995  # Find component cref refers to
996  try:
997  c = self.get_component_by_name(cref.component)
998  except KeyError:
999  self.validation_error("A component_ref element must reference a component in the current"
1000  " model (6.4.3.3). Component '%s' does not exist." % cref.component)
1001  return
1002  # Set c's parent to p
1003  c._set_parent_component(key, p)
1004  if hasattr(cref, 'component_ref'):
1005  # If we already have children under this hierarchy it's a validation error
1006  if c._has_child_components(key):
1007  self.validation_error("In a given hierarchy, only one component_ref element "
1008  "referencing a given component may contain children (6.4.3.2)."
1009  " Component '%s' has children in multiple locations." % c.name)
1010  # Set parent of c's children to c
1011  set_parent(c, cref.component_ref)
1012  elif p is None and namespace is None:
1013  self.validation_error("Containment and encapsulation relationships must be hierarchical"
1014  " (6.4.3.2). Potentially top-level component '%s' has not been"
1015  " given children." % cref.component)
1016  for group in groups:
1017  set_parent(None, group.component_ref)
1018  if self._cml_validation_errors:
1019  return
1020  # Check for a cycle in the hierarchy (rule 6.4.3.2 (4)).
1021  # Note that since we have already ensured that no component is a parent in more than one location,
1022  # nor is any component a child more than once, so the only possibility for a cycle is if one of
1023  # the components referenced as a child of a group element is also referenced as a (leaf) descendent
1024  # of one of its children. We check for this by following parent links backwards.
1025  def has_cycle(root_comp, cur_comp):
1026  if cur_comp is None:
1027  return False
1028  elif cur_comp is root_comp:
1029  return True
1030  else:
1031  return has_cycle(root_comp, cur_comp.parent(reln_key=key))
1032  for group in groups:
1033  for cref in group.component_ref:
1034  # Find component cref refers to
1035  c = self.get_component_by_name(cref.component)
1036  if has_cycle(c, c.parent(reln_key = key)):
1037  n, ns = name or "", namespace or ""
1038  self.validation_error("The '%s' relationship hierarchy with name '%s' and namespace"
1039  " '%s' has a cycle" % (relationship, n, ns))
1040  return
1041 

References CellMLToNektar.pycml.cellml_model._cml_validation_errors, CellMLToNektar.pycml.cellml_model.build_name_dictionaries(), CellMLToNektar.pycml.cellml_model.get_component_by_name(), and CellMLToNektar.pycml.cellml_model.validation_error().

Referenced by CellMLToNektar.pycml.cellml_model._validate_component_hierarchies().

◆ build_name_dictionaries()

def CellMLToNektar.pycml.cellml_model.build_name_dictionaries (   self,
  rebuild = False 
)
Create dictionaries mapping names of variables and components to
the objects representing them.
Dictionary keys for variables will be
  (component_name, variable_name).

If rebuild is True, clear the dictionaries first.

Definition at line 932 of file pycml.py.

932  def build_name_dictionaries(self, rebuild=False):
933  """
934  Create dictionaries mapping names of variables and components to
935  the objects representing them.
936  Dictionary keys for variables will be
937  (component_name, variable_name).
938 
939  If rebuild is True, clear the dictionaries first.
940  """
941  if rebuild:
942  self._cml_variables = {}
943  self._cml_components = {}
944  if not self._cml_components:
945  for comp in getattr(self, u'component', []):
946  if comp.name in self._cml_components:
947  self.validation_error("Component names must be unique within a model (3.4.2.2)."
948  " The name '%s' is repeated." % comp.name)
949  self._cml_components[comp.name] = comp
950  for var in getattr(comp, u'variable', []):
951  key = (comp.name, var.name)
952  if key in self._cml_variables:
953  self.validation_error("Variable names must be unique within a component (3.4.3.2)."
954  " The name '%s' is repeated in component '%s'."
955  % (var.name, comp.name))
956  self._cml_variables[key] = var
957 

References CellMLToNektar.pycml.cellml_model._cml_components, CellMLToNektar.pycml.cellml_model._cml_variables, and CellMLToNektar.pycml.cellml_model.validation_error().

Referenced by CellMLToNektar.pycml.cellml_model._check_variable_mappings(), and CellMLToNektar.pycml.cellml_model.build_component_hierarchy().

◆ calculate_extended_dependencies()

def CellMLToNektar.pycml.cellml_model.calculate_extended_dependencies (   self,
  nodes,
  prune = [],
  prune_deps = [],
  state_vars_depend_on_odes = False,
  state_vars_examined = set() 
)
Calculate the extended dependencies of the given nodes.

Recurse into the dependency graph, in order to construct a
set, for each node in nodes, of all the nodes on which it
depends, either directly or indirectly.

Each node IS included in its own dependency set.

If prune is specified, it should be a set of nodes for which
we won't include their dependencies or the nodes themselves.
This is useful e.g. for pruning variables required for calculating
a stimulus if the stimulus is being provided by another method.
prune_deps is similar: dependencies of these nodes will be excluded,
but the nodes themselves will be included if asked for.

If state_vars_depend_on_odes is True, then considers state variables
to depend on the ODE defining them.

Requires the dependency graph to be acyclic.

Return the union of all the dependency sets.

Definition at line 1378 of file pycml.py.

1381  state_vars_examined=set()):
1382  """Calculate the extended dependencies of the given nodes.
1383 
1384  Recurse into the dependency graph, in order to construct a
1385  set, for each node in nodes, of all the nodes on which it
1386  depends, either directly or indirectly.
1387 
1388  Each node IS included in its own dependency set.
1389 
1390  If prune is specified, it should be a set of nodes for which
1391  we won't include their dependencies or the nodes themselves.
1392  This is useful e.g. for pruning variables required for calculating
1393  a stimulus if the stimulus is being provided by another method.
1394  prune_deps is similar: dependencies of these nodes will be excluded,
1395  but the nodes themselves will be included if asked for.
1396 
1397  If state_vars_depend_on_odes is True, then considers state variables
1398  to depend on the ODE defining them.
1399 
1400  Requires the dependency graph to be acyclic.
1401 
1402  Return the union of all the dependency sets.
1403  """
1404  deps = set()
1405  for node in nodes:
1406  if node in prune or (isinstance(node, mathml_apply) and
1407  isinstance(node.operator(), mathml_eq) and
1408  isinstance(node.eq.lhs, mathml_ci) and
1409  node.eq.lhs.variable in prune):
1410  continue
1411  if type(node) == tuple:
1412  # This is an ODE dependency, so get the defining expression instead.
1413  ode = True
1414  orig_node = node
1415  node = node[0].get_ode_dependency(node[1])
1416  if orig_node in prune_deps:
1417  # Include the defining expression, but skip its dependencies
1418  deps.add(node)
1419  continue
1420  free_var = node.eq.lhs.diff.independent_variable
1421  else:
1422  ode = False
1423  deps.add(node)
1424  if node in prune_deps:
1425  # Skip dependencies of this node
1426  continue
1427  nodedeps = set(node.get_dependencies())
1428  if ode and not node._cml_ode_has_free_var_on_rhs:
1429  # ODEs depend on their independent variable. However,
1430  # when writing out code we don't want to pull the free
1431  # variable in just for this, as the compiler then
1432  # gives us unused variable warnings.
1433  nodedeps.remove(free_var)
1434  if (state_vars_depend_on_odes and isinstance(node, cellml_variable)
1435  and node.get_type() == VarTypes.State
1436  and node not in state_vars_examined):
1437  nodedeps.update(node.get_all_expr_dependencies())
1438  state_vars_examined.add(node)
1439  deps.update(self.calculate_extended_dependencies(nodedeps,
1440  prune=prune,
1441  prune_deps=prune_deps,
1442  state_vars_depend_on_odes=state_vars_depend_on_odes,
1443  state_vars_examined=state_vars_examined))
1444  return deps
1445 

References CellMLToNektar.translators.CellMLTranslator.calculate_extended_dependencies(), and CellMLToNektar.pycml.cellml_model.calculate_extended_dependencies().

Referenced by CellMLToNektar.pycml.cellml_model.calculate_extended_dependencies(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_backward_euler_mathematics(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_derivative_calculations(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_derivative_calculations_grl(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_derived_quantities(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_get_i_ionic(), CellMLToNektar.CellMLToNektarTranslator.CellMLToNektarTranslator.output_grl_compute_partial(), and CellMLToNektar.translators.CellMLTranslator.output_table_index_generation().

◆ clean_up()

def CellMLToNektar.pycml.cellml_model.clean_up (   self)
Try to get the RDF library to clean up nicely.

Definition at line 398 of file pycml.py.

398  def clean_up(self):
399  """Try to get the RDF library to clean up nicely."""
400  cellml_metadata.remove_model(self)
401 

Referenced by CellMLToNektar.pycml.cellml_model.__del__().

◆ clear_assignments()

def CellMLToNektar.pycml.cellml_model.clear_assignments (   self)
Clear the assignments list.

Definition at line 1120 of file pycml.py.

1120  def clear_assignments(self):
1121  """Clear the assignments list."""
1122  self._cml_assignments = []
1123 

References CellMLToNektar.pycml.cellml_model._cml_assignments.

Referenced by CellMLToNektar.pycml.cellml_model._order_variables().

◆ do_binding_time_analysis()

def CellMLToNektar.pycml.cellml_model.do_binding_time_analysis (   self)
Perform a binding time analysis on the model's mathematics.

This requires variables to have been classified and a
topological sort of the mathematics to have been performed.

Variables and top-level expressions are processed in the order
given by the topological sort, hence only a single pass is
necessary.

Variables are classified based on their type:
  State, Free -> dynamic
  Constant -> static
  Mapped -> binding time of source variable
  Computed -> binding time of defining expression

Expressions are dealt with by recursively annotating
subexpressions.  See code in the MathML classes for details.

Definition at line 1124 of file pycml.py.

1124  def do_binding_time_analysis(self):
1125  """Perform a binding time analysis on the model's mathematics.
1126 
1127  This requires variables to have been classified and a
1128  topological sort of the mathematics to have been performed.
1129 
1130  Variables and top-level expressions are processed in the order
1131  given by the topological sort, hence only a single pass is
1132  necessary.
1133 
1134  Variables are classified based on their type:
1135  State, Free -> dynamic
1136  Constant -> static
1137  Mapped -> binding time of source variable
1138  Computed -> binding time of defining expression
1139 
1140  Expressions are dealt with by recursively annotating
1141  subexpressions. See code in the MathML classes for details.
1142  """
1143  for item in self.get_assignments():
1144  if isinstance(item, cellml_variable):
1145  # Set binding time based on type
1146  item._get_binding_time()
1147  else:
1148  # Compute binding time recursively
1149  item._get_binding_time()
1150 

References CellMLToNektar.pycml.cellml_model.get_assignments().

◆ find_free_vars()

def CellMLToNektar.pycml.cellml_model.find_free_vars (   self)
Return a list of the free variable elements in this model.

Definition at line 1370 of file pycml.py.

1370  def find_free_vars(self):
1371  """Return a list of the free variable elements in this model."""
1372  free_vars = []
1373  for var in self.get_all_variables():
1374  if var.get_type() == VarTypes.Free:
1375  free_vars.append(var)
1376  return free_vars
1377 

References CellMLToNektar.pycml.cellml_model.get_all_variables().

◆ find_state_vars()

def CellMLToNektar.pycml.cellml_model.find_state_vars (   self)
Return a list of the state variable elements in this model.

Definition at line 1362 of file pycml.py.

1362  def find_state_vars(self):
1363  """Return a list of the state variable elements in this model."""
1364  state_vars = []
1365  for var in self.get_all_variables():
1366  if var.get_type() == VarTypes.State:
1367  state_vars.append(var)
1368  return state_vars
1369 

References CellMLToNektar.pycml.cellml_model.get_all_variables().

◆ get_all_units()

def CellMLToNektar.pycml.cellml_model.get_all_units (   self)
Get a list of all units objects, including the standard units.

Definition at line 1300 of file pycml.py.

1300  def get_all_units(self):
1301  """Get a list of all units objects, including the standard units."""
1302  if not self._cml_units:
1303  self._build_units_dictionary()
1304  units = self._cml_units.values()
1305  for comp in getattr(self, u'component', []):
1306  units.extend(comp.get_all_units())
1307  return units
1308 

References CellMLToNektar.pycml.cellml_model._build_units_dictionary(), CellMLToNektar.pycml.cellml_component._build_units_dictionary(), CellMLToNektar.pycml.cellml_model._cml_units, CellMLToNektar.pycml.cellml_component._cml_units, CellMLToNektar.pycml.mathml_units_mixin_tokens._cml_units, CellMLToNektar.pycml.mathml_units_mixin_container._cml_units, CellMLToNektar.pycml.mathml_cn._cml_units, CellMLToNektar.pycml.mathml_ci._cml_units, CellMLToNektar.pycml.mathml_apply._cml_units, and CellMLToNektar.pycml.mathml_piecewise._cml_units.

Referenced by CellMLToNektar.pycml.cellml_model.validate().

◆ get_all_variables()

def CellMLToNektar.pycml.cellml_model.get_all_variables (   self)
Return an iterator over the variables in the model.

Definition at line 484 of file pycml.py.

484  def get_all_variables(self):
485  """Return an iterator over the variables in the model."""
486  for comp in getattr(self, u'component', []):
487  for var in getattr(comp, u'variable', []):
488  yield var
489 

Referenced by CellMLToNektar.pycml.cellml_model._check_variable_units_exist(), CellMLToNektar.pycml.cellml_model._classify_variables(), CellMLToNektar.pycml.cellml_model.find_free_vars(), and CellMLToNektar.pycml.cellml_model.find_state_vars().

◆ get_assignments()

def CellMLToNektar.pycml.cellml_model.get_assignments (   self)
Return a sorted list of all the assignments in the model.

Assignments can either be instances of cellml_variable, in
which case they represent a variable mapping, or instances of
mathml_apply, representing top-level assignment expressions.

Definition at line 1111 of file pycml.py.

1111  def get_assignments(self):
1112  """
1113  Return a sorted list of all the assignments in the model.
1114 
1115  Assignments can either be instances of cellml_variable, in
1116  which case they represent a variable mapping, or instances of
1117  mathml_apply, representing top-level assignment expressions.
1118  """
1119  return self._cml_assignments

References CellMLToNektar.pycml.cellml_model._cml_assignments.

Referenced by CellMLToNektar.pycml.cellml_model.do_binding_time_analysis().

◆ get_component_by_name()

def CellMLToNektar.pycml.cellml_model.get_component_by_name (   self,
  compname 
)
Return the component object that has name `compname'.

Definition at line 414 of file pycml.py.

414  def get_component_by_name(self, compname):
415  """Return the component object that has name `compname'."""
416  return self._cml_components[compname]
417 

References CellMLToNektar.pycml.cellml_model._cml_components.

Referenced by CellMLToNektar.pycml.cellml_model._check_connection_units(), CellMLToNektar.pycml.cellml_model._validate_connection(), and CellMLToNektar.pycml.cellml_model.build_component_hierarchy().

◆ get_config()

def CellMLToNektar.pycml.cellml_model.get_config (   self,
  config_attr = None 
)
Get the configuration store if it exists, or an attribute thereof.

Definition at line 402 of file pycml.py.

402  def get_config(self, config_attr=None):
403  """Get the configuration store if it exists, or an attribute thereof."""
404  config = getattr(self.xml_parent, '_cml_config', None)
405  if config_attr:
406  config = getattr(config, config_attr, None)
407  return config
408 

◆ get_option()

def CellMLToNektar.pycml.cellml_model.get_option (   self,
  option_name 
)
Get the value of a command-line option.

Definition at line 409 of file pycml.py.

409  def get_option(self, option_name):
410  """Get the value of a command-line option."""
411  config = getattr(self.xml_parent, '_cml_config', None)
412  return config and getattr(config.options, option_name)
413 

◆ get_standard_units()

def CellMLToNektar.pycml.cellml_model.get_standard_units (   self)
Get a dictionary mapping the names of the standard CellML units to their definitions.

Definition at line 1294 of file pycml.py.

1294  def get_standard_units(self):
1295  """Get a dictionary mapping the names of the standard CellML units to their definitions."""
1296  if not self._cml_standard_units:
1297  self._build_units_dictionary()
1298  return self._cml_standard_units
1299 

References CellMLToNektar.pycml.cellml_model._build_units_dictionary(), CellMLToNektar.pycml.cellml_component._build_units_dictionary(), and CellMLToNektar.pycml.cellml_model._cml_standard_units.

◆ get_units_by_name()

def CellMLToNektar.pycml.cellml_model.get_units_by_name (   self,
  uname 
)
Return an object representing the element that defines the units named `uname'.

Definition at line 1309 of file pycml.py.

1309  def get_units_by_name(self, uname):
1310  """Return an object representing the element that defines the units named `uname'."""
1311  if not self._cml_units:
1312  self._build_units_dictionary()
1313  try:
1314  return self._cml_units[uname]
1315  except KeyError:
1316  raise KeyError("Units '%s' are not defined in the current component or model." % uname)
1317 
def get_units_by_name(self, uname)
Definition: pycml.py:2725

References CellMLToNektar.pycml.cellml_model._build_units_dictionary(), CellMLToNektar.pycml.cellml_component._build_units_dictionary(), CellMLToNektar.pycml.cellml_model._cml_units, CellMLToNektar.pycml.cellml_component._cml_units, CellMLToNektar.pycml.mathml_units_mixin_tokens._cml_units, CellMLToNektar.pycml.mathml_units_mixin_container._cml_units, CellMLToNektar.pycml.mathml_cn._cml_units, CellMLToNektar.pycml.mathml_ci._cml_units, CellMLToNektar.pycml.mathml_apply._cml_units, and CellMLToNektar.pycml.mathml_piecewise._cml_units.

◆ get_validation_errors()

def CellMLToNektar.pycml.cellml_model.get_validation_errors (   self)
Return the list of all errors found (so far) while validating this model.

Definition at line 519 of file pycml.py.

519  def get_validation_errors(self):
520  """Return the list of all errors found (so far) while validating this model."""
521  return self._cml_validation_errors
def get_validation_errors(self)
Definition: validator.py:323

References CellMLToNektar.pycml.cellml_model._cml_validation_errors.

◆ get_validation_warnings()

def CellMLToNektar.pycml.cellml_model.get_validation_warnings (   self)
Return the list of all warnings found (so far) while validating this model.

Definition at line 529 of file pycml.py.

529  def get_validation_warnings(self):
530  """Return the list of all warnings found (so far) while validating this model.
531  """
532  return self._cml_validation_warnings

References CellMLToNektar.pycml.cellml_model._cml_validation_warnings.

◆ get_variable_by_cmeta_id()

def CellMLToNektar.pycml.cellml_model.get_variable_by_cmeta_id (   self,
  cmeta_id 
)
Get the unique variable in this model with the given cmeta:id attribute value.

Definition at line 474 of file pycml.py.

474  def get_variable_by_cmeta_id(self, cmeta_id):
475  """
476  Get the unique variable in this model with the given cmeta:id attribute value.
477  """
478  vars = self.xml_xpath(u'cml:component/cml:variable[@cmeta:id="%s"]' % cmeta_id)
479  if len(vars) != 1:
480  raise ValueError('"%s" does not ID a unique variable (matches: %s)'
481  % (cmeta_id, str(vars)))
482  return vars[0]
483 

◆ get_variable_by_name()

def CellMLToNektar.pycml.cellml_model.get_variable_by_name (   self,
  compname,
  varname 
)
Return the variable object with name `varname' in component
`compname'.

Definition at line 418 of file pycml.py.

418  def get_variable_by_name(self, compname, varname):
419  """
420  Return the variable object with name `varname' in component
421  `compname'.
422  """
423  try:
424  var = self._cml_variables[(compname, varname)]
425  except KeyError, e:
426  if compname == u'':
427  if self.component.ignore_component_name:
428  compname = self.component.name
429  else:
430  try:
431  compname, varname = cellml_variable.split_name(varname)
432  except ValueError:
433  raise e
434  var = self._cml_variables[(compname, varname)]
435  else:
436  raise e
437  return var
438 

References CellMLToNektar.pycml.cellml_model._cml_variables, CellMLToNektar.pycml.cellml_variable.component, and CellMLToNektar.pycml.mathml.component.

Referenced by CellMLToNektar.pycml.cellml_model._check_connection_units(), and CellMLToNektar.pycml.cellml_model._validate_connection().

◆ get_variable_by_oxmeta_name()

def CellMLToNektar.pycml.cellml_model.get_variable_by_oxmeta_name (   self,
  name,
  throw = True 
)
Get the unique variable in this model with the given Oxford metadata
name annotation.

If throw is True, will raise ValueError if there is no such variable,
or more than 1 match.  If throw is False, returns None in these cases.

Definition at line 439 of file pycml.py.

439  def get_variable_by_oxmeta_name(self, name, throw=True):
440  """
441  Get the unique variable in this model with the given Oxford metadata
442  name annotation.
443 
444  If throw is True, will raise ValueError if there is no such variable,
445  or more than 1 match. If throw is False, returns None in these cases.
446  """
447  vars = cellml_metadata.find_variables(self,
448  ('bqbiol:is', NSS['bqbiol']),
449  ('oxmeta:'+str(name), NSS['oxmeta']))
450  if len(vars) == 1:
451  var = vars[0]
452  elif throw:
453  raise ValueError('"%s" does not name a unique variable (matches: %s)'
454  % (name, str(vars)))
455  else:
456  var = None
457  return var
458 

◆ get_variables_by_ontology_term()

def CellMLToNektar.pycml.cellml_model.get_variables_by_ontology_term (   self,
  term 
)
Return a list of variables annotated with the given ontology term.

The annotations have the same form as for oxmeta name annotations (see
get_variable_by_oxmeta_name).  However, here we are not restricted to
namespace, and no check is done on the number of results returned.

The given term must be a (prefixed_name, nsuri) tuple.

Definition at line 459 of file pycml.py.

459  def get_variables_by_ontology_term(self, term):
460  """Return a list of variables annotated with the given ontology term.
461 
462  The annotations have the same form as for oxmeta name annotations (see
463  get_variable_by_oxmeta_name). However, here we are not restricted to
464  namespace, and no check is done on the number of results returned.
465 
466  The given term must be a (prefixed_name, nsuri) tuple.
467  """
468  assert isinstance(term, tuple)
469  assert len(term) == 2
470  named_vars = cellml_metadata.find_variables(self, ('bqbiol:is', NSS['bqbiol']), term)
471  category_vars = cellml_metadata.find_variables(self, ('bqbiol:isVersionOf', NSS['bqbiol']), term)
472  return named_vars + category_vars
473 

◆ has_units()

def CellMLToNektar.pycml.cellml_model.has_units (   self,
  units 
)
Test whether a given units definition appears in the model.

Definition at line 1327 of file pycml.py.

1327  def has_units(self, units):
1328  """Test whether a given units definition appears in the model."""
1329  return units in self._cml_units.itervalues()
1330 

References CellMLToNektar.pycml.cellml_model._cml_units, CellMLToNektar.pycml.cellml_component._cml_units, CellMLToNektar.pycml.mathml_units_mixin_tokens._cml_units, CellMLToNektar.pycml.mathml_units_mixin_container._cml_units, CellMLToNektar.pycml.mathml_cn._cml_units, CellMLToNektar.pycml.mathml_ci._cml_units, CellMLToNektar.pycml.mathml_apply._cml_units, and CellMLToNektar.pycml.mathml_piecewise._cml_units.

◆ is_self_excitatory()

def CellMLToNektar.pycml.cellml_model.is_self_excitatory (   self)
Determine whether this model is self-excitatory,
i.e. does not require an external stimulus.

Definition at line 1446 of file pycml.py.

1446  def is_self_excitatory(self):
1447  """Determine whether this model is self-excitatory,
1448  i.e. does not require an external stimulus.
1449  """
1450  meta_id = self.cmeta_id
1451  if not meta_id:
1452  return False
1453  property = cellml_metadata.create_rdf_node(('pycml:is-self-excitatory', NSS['pycml']))
1454  source = cellml_metadata.create_rdf_node(fragment_id=meta_id)
1455  return cellml_metadata.get_target(self, source, property) == 'yes'
1456 

References CellMLToNektar.pycml.element_base.cmeta_id().

◆ search_for_assignments()

def CellMLToNektar.pycml.cellml_model.search_for_assignments (   self,
  comp = None 
)
Search for assignment expressions in the model's mathematics.

If comp is supplied, will only return assignments in that component.

Definition at line 918 of file pycml.py.

918  def search_for_assignments(self, comp=None):
919  """Search for assignment expressions in the model's mathematics.
920 
921  If comp is supplied, will only return assignments in that component.
922  """
923  assignments_xpath = u' | '.join([self.math_xpath_1 + self.apply_xpath_1,
924  self.math_xpath_1 + self.apply_xpath_2,
925  self.math_xpath_2 + self.apply_xpath_1,
926  self.math_xpath_2 + self.apply_xpath_2])
927  if comp:
928  assignments_xpath = assignments_xpath.replace(u'component',
929  u'component[@name="%s"]' % comp.name)
930  return self.xml_xpath(assignments_xpath)
931 

References CellMLToNektar.pycml.cellml_model.apply_xpath_1, CellMLToNektar.pycml.cellml_model.apply_xpath_2, CellMLToNektar.pycml.cellml_model.math_xpath_1, and CellMLToNektar.pycml.cellml_model.math_xpath_2.

Referenced by CellMLToNektar.pycml.cellml_model.validate().

◆ topological_sort()

def CellMLToNektar.pycml.cellml_model.topological_sort (   self,
  node 
)
Do a topological sort of all assignment expressions and variables
in the model.

node should be an expression or variable object that inherits from
Colourable and has methods get_dependencies, get_component

Definition at line 1042 of file pycml.py.

1042  def topological_sort(self, node):
1043  """
1044  Do a topological sort of all assignment expressions and variables
1045  in the model.
1046 
1047  node should be an expression or variable object that inherits from
1048  Colourable and has methods get_dependencies, get_component
1049  """
1050  node.set_colour(DFS.Gray)
1051  # Keep track of gray variables, for reporting cycles
1052  if isinstance(node, cellml_variable):
1053  self._cml_sorting_variables_stack.append(node.fullname())
1054  elif node.is_ode():
1055  # This is an expression defining an ODE; the name on the
1056  # stack will look something like d(V)/d(t)
1057  n1, n2 = map(lambda v: v.fullname(), node.assigned_variable())
1058  self._cml_sorting_variables_stack.append(u'd'+n1+u'/d'+n2)
1059  # Visit children in the dependency graph
1060  for dep in node.get_dependencies():
1061  if type(dep) == types.TupleType:
1062  # This is an ODE dependency, so get the defining expression
1063  dep = dep[0].get_ode_dependency(dep[1], node)
1064  if dep.get_colour() == DFS.White:
1065  self.topological_sort(dep)
1066  elif dep.get_colour() == DFS.Gray:
1067  # We have a cyclic dependency
1068  if isinstance(dep, cellml_variable):
1069  i = self._cml_sorting_variables_stack.index(dep.fullname())
1070  elif node.is_ode():
1071  n1, n2 = map(lambda v: v.fullname(),
1072  dep.assigned_variable())
1073  i = self._cml_sorting_variables_stack.index(
1074  u'd'+n1+u'/d'+n2)
1075  else:
1076  # Since any variable always depends on a mathematical
1077  # expression defining it, the only case where the
1078  # expression is gray before the corresponding variable
1079  # (apart from an ODE, dealt with above) is if a tree
1080  # started at an expression. Hence the whole stack
1081  # is in the cycle.
1082  i = 0
1083  varnames = self._cml_sorting_variables_stack[i:]
1084  self.validation_error(u' '.join([
1085  u'There is a cyclic dependency involving the following',
1086  u'variables:', u','.join(varnames)]))
1087  # Finish this node, and add it to the appropriate sorted list
1088  node.set_colour(DFS.Black)
1089  self._add_sorted_assignment(node)
1090  # Pop the gray variables stack
1091  if (isinstance(node, cellml_variable) or node.is_ode()):
1092  self._cml_sorting_variables_stack.pop()
1093  return
1094 

References CellMLToNektar.pycml.cellml_model._add_sorted_assignment(), CellMLToNektar.pycml.cellml_model._cml_sorting_variables_stack, CellMLToNektar.pycml.cellml_model.topological_sort(), and CellMLToNektar.pycml.cellml_model.validation_error().

Referenced by CellMLToNektar.pycml.cellml_model.topological_sort().

◆ validate()

def CellMLToNektar.pycml.cellml_model.validate (   self,
  xml_context = False,
  invalid_if_warnings = False,
  warn_on_units_errors = False,
  check_for_units_conversions = False,
  assume_valid = False,
**  ignored_kwargs 
)
Validate this model.

Assumes that RELAX NG validation has been done.  Checks rules
3.4.2.2, 3.4.3.2, 3.4.3.3, 3.4.5.2, 3.4.5.3, 3.4.5.4, 3.4.6.2, 3.4.6.3, 3.4.6.4,
4.4.2.1, 4.4.3.2, 4.4.4, 5.4.1.2, 5.4.2.2, 6.4.2.5, 6.4.3.2, and 6.4.3.3
in the CellML 1.0 spec, and performs units checking.

Note that if some checks fail, most of the remaining checks
will not be performed.  Hence when testing a model validate
repeatedly until it passes.

If xml_context is True, then the failing MathML tree will be
displayed with every units error.

If check_for_units_conversions is True, then generate a warning if
units conversions will be needed.

If assume_valid is True then fewer checks will be done - only
what is required to set up the data structures needed for model
transformation.

Returns True iff the model validates.
When invalid_if_warnings is True the model will fail to validate
if there are any warnings, as well as if there are any errors.

Definition at line 545 of file pycml.py.

549  assume_valid=False, **ignored_kwargs):
550  """Validate this model.
551 
552  Assumes that RELAX NG validation has been done. Checks rules
553  3.4.2.2, 3.4.3.2, 3.4.3.3, 3.4.5.2, 3.4.5.3, 3.4.5.4, 3.4.6.2, 3.4.6.3, 3.4.6.4,
554  4.4.2.1, 4.4.3.2, 4.4.4, 5.4.1.2, 5.4.2.2, 6.4.2.5, 6.4.3.2, and 6.4.3.3
555  in the CellML 1.0 spec, and performs units checking.
556 
557  Note that if some checks fail, most of the remaining checks
558  will not be performed. Hence when testing a model validate
559  repeatedly until it passes.
560 
561  If xml_context is True, then the failing MathML tree will be
562  displayed with every units error.
563 
564  If check_for_units_conversions is True, then generate a warning if
565  units conversions will be needed.
566 
567  If assume_valid is True then fewer checks will be done - only
568  what is required to set up the data structures needed for model
569  transformation.
570 
571  Returns True iff the model validates.
572  When invalid_if_warnings is True the model will fail to validate
573  if there are any warnings, as well as if there are any errors.
574  """
575  self._validate_component_hierarchies()
576 
577  # Rule 5.4.2.2: units definitions may not be circular.
578  # Also checks 5.4.1.2: no duplicate units names.
579  if not assume_valid:
580  for unit in self.get_all_units():
581  self._check_unit_cycles(unit)
582  DEBUG('validator', 'Checked for units cycles')
583  # Check rule 3.4.3.3 too.
584  self._check_variable_units_exist()
585 
586  if not self._cml_validation_errors:
587  self._check_variable_mappings() # This sets up source variable links
588  if not self._cml_validation_errors and not assume_valid:
589  self._check_connection_units(check_for_units_conversions)
590 
591  # Rules 4.4.2.1 and 4.4.3.2: check name references in mathematics
592  if not self._cml_validation_errors:
593  assignment_exprs = self.search_for_assignments()
594  if not assume_valid:
595  for expr in assignment_exprs:
596  self._check_maths_name_references(expr, xml_context)
597 
598  # Rule 4.4.4: mathematical expressions may only modify
599  # variables belonging to the current component.
600  if not self._cml_validation_errors and not assume_valid:
601  self._check_assigned_vars(assignment_exprs, xml_context)
602 
603  # Warn if mathematics outside the CellML subset is used.
604  if not self._cml_validation_errors and not assume_valid:
605  math_elts = self.xml_xpath(self.math_xpath_1 + u' | ' + self.math_xpath_2)
606  self._check_cellml_subset(math_elts)
607 
608  # Classify variables and check for circular equations.
609  # Does a topological sort of all equations in the process.
610  # TODO: Handle reactions properly.
611  if not self._cml_validation_errors:
612  self._classify_variables(assignment_exprs, xml_context)
613  self._order_variables(assignment_exprs, xml_context)
614 
615  # Appendix C.3.6: Equation dimension checking.
616  if not self._cml_validation_errors and (not assume_valid or check_for_units_conversions):
617  self._check_dimensional_consistency(assignment_exprs,
618  xml_context,
619  warn_on_units_errors,
620  check_for_units_conversions)
621 
622  # Warn if unknown namespaces are used, just in case.
623  unknown_nss = set(self.rootNode.xml_namespaces.keys()).difference(set(NSS.values()))
624  if unknown_nss:
625  self.validation_warning(u'Unrecognised namespaces used:\n ' +
626  u'\n '.join(list(unknown_nss)))
627 
628  # Return validation result
629  return not self._cml_validation_errors and \
630  (not invalid_if_warnings or not self._cml_validation_warnings)
631 

References CellMLToNektar.pycml.cellml_model._check_assigned_vars(), CellMLToNektar.pycml.cellml_model._check_cellml_subset(), CellMLToNektar.pycml.cellml_model._check_connection_units(), CellMLToNektar.pycml.cellml_model._check_dimensional_consistency(), CellMLToNektar.pycml.cellml_model._check_maths_name_references(), CellMLToNektar.pycml.cellml_model._check_unit_cycles(), CellMLToNektar.pycml.cellml_model._check_variable_mappings(), CellMLToNektar.pycml.cellml_model._check_variable_units_exist(), CellMLToNektar.pycml.cellml_model._classify_variables(), CellMLToNektar.pycml.cellml_model._cml_validation_errors, CellMLToNektar.pycml.cellml_model._cml_validation_warnings, CellMLToNektar.pycml.cellml_model._order_variables(), CellMLToNektar.pycml.cellml_model._validate_component_hierarchies(), CellMLToNektar.utilities.DEBUG(), CellMLToNektar.pycml.cellml_model.get_all_units(), CellMLToNektar.pycml.cellml_component.get_all_units(), CellMLToNektar.pycml.cellml_model.math_xpath_1, CellMLToNektar.pycml.cellml_model.math_xpath_2, CellMLToNektar.pycml.element_base.rootNode(), CellMLToNektar.pycml.cellml_model.search_for_assignments(), and CellMLToNektar.pycml.cellml_model.validation_warning().

◆ validation_error()

def CellMLToNektar.pycml.cellml_model.validation_error (   self,
  errmsg,
  level = logging.ERROR 
)

◆ validation_warning()

def CellMLToNektar.pycml.cellml_model.validation_warning (   self,
  errmsg,
  level = logging.WARNING 
)
Log a validation warning message.

Message should be a unicode string.

Definition at line 522 of file pycml.py.

522  def validation_warning(self, errmsg, level=logging.WARNING):
523  """Log a validation warning message.
524 
525  Message should be a unicode string.
526  """
527  self._cml_validation_warnings.append(errmsg)
528  logging.getLogger('validator').log(level, errmsg.encode('UTF-8'))

References CellMLToNektar.pycml.cellml_model._cml_validation_warnings, and tinysimd.log().

Referenced by CellMLToNektar.pycml.cellml_model._check_cellml_subset(), CellMLToNektar.pycml.cellml_model._check_connection_units(), CellMLToNektar.pycml.cellml_model._report_exception(), and CellMLToNektar.pycml.cellml_model.validate().

◆ xml()

def CellMLToNektar.pycml.cellml_model.xml (   self,
  stream = None,
  writer = None,
**  wargs 
)
Serialize back to XML.
If stream is given, output to stream.
If writer is given, use it directly.
If neither a stream nor a writer is given, return the output text
as a Python string (not Unicode) encoded as UTF-8.

This overrides Amara's method, in order to force declaration of
various namespaces with prefixes on this element, and to ensure
the RDF annotations are up-to-date.

See base class docs for possible keyword arguments.

Definition at line 1457 of file pycml.py.

1457  def xml(self, stream=None, writer=None, **wargs):
1458  """Serialize back to XML.
1459  If stream is given, output to stream.
1460  If writer is given, use it directly.
1461  If neither a stream nor a writer is given, return the output text
1462  as a Python string (not Unicode) encoded as UTF-8.
1463 
1464  This overrides Amara's method, in order to force declaration of
1465  various namespaces with prefixes on this element, and to ensure
1466  the RDF annotations are up-to-date.
1467 
1468  See base class docs for possible keyword arguments.
1469  """
1470  extra_namespaces = {u'cellml': NSS[u'cml'],
1471  u'pe': NSS[u'pe'],
1472  u'lut': NSS[u'lut']}
1473 
1474  # Update RDF block if necessary
1475  cellml_metadata.update_serialized_rdf(self)
1476 
1477  temp_stream = None
1478  close_document = 0
1479  if not writer:
1480  #Change the default to *not* generating an XML decl
1481  if not wargs.get('omitXmlDeclaration'):
1482  wargs['omitXmlDeclaration'] = u'yes'
1483  if stream:
1484  writer = amara.bindery.create_writer(stream, wargs)
1485  else:
1486  temp_stream = StringIO()
1487  writer = amara.bindery.create_writer(temp_stream, wargs)
1488 
1489  writer.startDocument()
1490  close_document = 1
1491  writer.startElement(self.nodeName, self.namespaceURI,
1492  extraNss=extra_namespaces)
1493  if hasattr(self, 'xml_attributes'):
1494  for apyname in self.xml_attributes:
1495  aqname, ans = self.xml_attributes[apyname]
1496  val = self.__dict__[apyname]
1497  writer.attribute(aqname, val, ans)
1498  for child in self.xml_children:
1499  if isinstance(child, unicode):
1500  writer.text(child)
1501  else:
1502  child.xml(writer=writer)
1503  writer.endElement(self.nodeName, self.namespaceURI)
1504  if close_document:
1505  writer.endDocument()
1506  return temp_stream and temp_stream.getvalue()
1507 
1508 

References CellMLToNektar.pycml.element_base.xml_attributes.

Member Data Documentation

◆ _cml_assignments

CellMLToNektar.pycml.cellml_model._cml_assignments
private

◆ _cml_components

CellMLToNektar.pycml.cellml_model._cml_components
private

◆ _cml_conversions_needed

CellMLToNektar.pycml.cellml_model._cml_conversions_needed
private

Definition at line 1156 of file pycml.py.

◆ _cml_sorting_variables_stack

CellMLToNektar.pycml.cellml_model._cml_sorting_variables_stack
private

Definition at line 902 of file pycml.py.

Referenced by CellMLToNektar.pycml.cellml_model.topological_sort().

◆ _cml_standard_units

CellMLToNektar.pycml.cellml_model._cml_standard_units
private

◆ _cml_units

CellMLToNektar.pycml.cellml_model._cml_units
private

◆ _cml_units_map

CellMLToNektar.pycml.cellml_model._cml_units_map
private

◆ _cml_validation_errors

CellMLToNektar.pycml.cellml_model._cml_validation_errors
private

◆ _cml_validation_warnings

CellMLToNektar.pycml.cellml_model._cml_validation_warnings
private

◆ _cml_variables

CellMLToNektar.pycml.cellml_model._cml_variables
private

◆ apply_xpath_1

string CellMLToNektar.pycml.cellml_model.apply_xpath_1 = u'/m:apply[m:eq]'
static

Definition at line 915 of file pycml.py.

Referenced by CellMLToNektar.pycml.cellml_model.search_for_assignments().

◆ apply_xpath_2

string CellMLToNektar.pycml.cellml_model.apply_xpath_2 = u'/m:semantics/m:apply[m:eq]'
static

Definition at line 916 of file pycml.py.

Referenced by CellMLToNektar.pycml.cellml_model.search_for_assignments().

◆ math_xpath_1

string CellMLToNektar.pycml.cellml_model.math_xpath_1 = u'cml:component/m:math'
static

◆ math_xpath_2

string CellMLToNektar.pycml.cellml_model.math_xpath_2 = u'cml:component/cml:reaction/cml:variable_ref/cml:role/m:math'
static