Source code for msml.run.memory
# region gplv3preamble
# The Medical Simulation Markup Language (MSML) - Simplifying the biomechanical modeling workflow
#
# MSML has been developed in the framework of 'SFB TRR 125 Cognition-Guided Surgery'
#
# If you use this software in academic work, please cite the paper:
# S. Suwelack, M. Stoll, S. Schalck, N.Schoch, R. Dillmann, R. Bendl, V. Heuveline and S. Speidel,
# The Medical Simulation Markup Language (MSML) - Simplifying the biomechanical modeling workflow,
# Medicine Meets Virtual Reality (MMVR) 2014
#
# Copyright (C) 2013-2014 see Authors.txt
#
# If you have any questions please feel free to contact us at suwelack@kit.edu
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# endregion
__author__ = 'Alexander Weigl <uiduw@student.kit.edu>'
import pprint
from ..model import parse_attribute_value, MSMLVariable
class MemoryError(Exception):
"""Generic Memory Error.
"""
pass
class MemoryTypeMismatchError(MemoryError):
"""Raises if the type of the given value does not match the pinned type in the memory"""
pass
class MemoryVariableUnknownError(MemoryError):
"""Raises if given variable is not in the memory"""
pass
[docs]class Memory(object):
"""The memory encapsulate dict helpers.
:param predefine_variables: a dict of predefined values for
the internal memory
:type predefine_variables: dict[str, object]
"""
def __init__(self, predefine_variables={}):
self._internal = {} # stores the variable value
self._meta = {} # stores the metadata for each variable name
def __getitem__(self, item):
"""get value from memory (raw access)"""
return self._internal[item]
def __setitem__(self, key, value):
"""set value into memory (raw access)"""
# TODO compatibility of variable and metadata (if meta is set)
r = self._internal[key] = value
return r
def __contains__(self, item):
return self._internal.__contains__(item)
[docs] def is_compatible(self, name):
#TODO
pass
[docs] def reset(self):
"""empties the internal memory"""
self._internal = {}
[docs] def load_memory_file(self, filename):
"""load the given file into the internal dict.
The given `filename` is executed and the defined
variables will be set into the internal memory.
:param filename: a path to a python (executable) file
:type filename:" str
"""
mem = {}
execfile(filename, mem)
self._internal.update(mem)
[docs] def show_content(self):
"""pretty print the internal dict to console"""
pprint.pprint(self._internal)
[docs] def lookup(self, reference):
"""lookup a reference
A refernce consists of task and slot name.
This method handles:
:str: e.g. "${taskA.slotB}" via
:py:func:`msml.model.parse_attribute_value`
:MSMLVariable:
:Reference:
:param reference: a reference to task and slot
:type reference: str or msml.model.Reference
"""
if isinstance(reference, str):
reference = parse_attribute_value(reference)
if isinstance(reference.linked_from.task, MSMLVariable):
return self[reference.linked_from.task.name]
return self[reference.linked_from.task.id][reference.linked_from.name]
[docs] def update(self, other):
if not other:
return
if isinstance(other, Memory):
internal = other._internal
else:
internal = other
assert isinstance(internal, dict)
self._internal = merge_dict(self._internal, internal)
def merge_dict(base, update):
"""merges to dictionaries
>>> merge_dict({}, {})
{}
>>> merge_dict({}, {'a':1})
{'a':1}
>>> merge_dict({'a':1},{'a':2, 'b':1})
{'a':2,'b':1}
"""
result = {}
keys = list(base.keys()) + list(update.keys())
for key in keys:
try:
new = update[key]
try:
current = base[key]
# assert key in (update, base)
if isinstance(new, dict) and isinstance(current, dict):
result[key] = merge_dict(current, new)
else:
result[key] = new
except:
result[key] = new
except KeyError as e: # key not in update
result[key] = base[key]
return result