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 __init__ (self)
 
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._classify_variables(), and 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._check_variable_mappings(), 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