Source code for tecplot.session.aux_data

import ctypes
import itertools as it
from collections import namedtuple
from contextlib import contextmanager
from enum import Enum

from ..tecutil import _tecutil
from ..constant import *
from ..exception import *
from ..tecutil import lock, lock_attributes


[docs]@lock_attributes class AuxData(ctypes.c_void_p): """Auxiliary data. The |Tecplot Engine| can hold auxiliary data attached to one of the following objects: - `Layout <layout.aux_data>` - `Page <Page.aux_data>` - `Frame <Frame.aux_data>` - `Dataset <Dataset.aux_data>` - `Variable <Variable.aux_data>` - `Zone <OrderedZone.aux_data>` - `Linemap <XYLinemap.aux_data>` Auxiliary data is an ordered key-value pair that behaves like an ordered dictionary, or `OrderedDict <collections.OrderedDict>`. Keys are strings which are ordered alphabetically and values can additionally be access by index. The keys must be alphanumeric (special characters "." and "_" are allowed), must not contain spaces, and must begin with a non-numeric character or underscore. Values, on the other hand, are arbitrary strings and can contain anything except the null character. In this example, we query the auxiliary data attached to the dataset and add some information to it. Notice that the stored order is alphabetical: .. code-block:: python import tecplot as tp aux = tp.active_frame().aux_data aux['info'] = 'Here is some information.' aux['Xavg'] = 3.14159 aux['note'] = 'Aux data values are always converted to strings.' ''' The following code will print: info: Here is some information. note: Aux data values are always converted to strings. Xavg: 3.14159 ''' for k, v in aux.items(): print('{}: {}'.format(k,v)) """ def __init__(self, parent, object_type, object_index=None): self.parent = parent self.object_type = object_type self.getref_args = [] if object_index is None else [object_index + 1] super().__init__(self._native_reference) @property def _native_reference(self): _dispatch = { AuxDataObjectType.Dataset: _tecutil.AuxDataDataSetGetRef, AuxDataObjectType.Frame: _tecutil.AuxDataFrameGetRef, AuxDataObjectType.Layout: _tecutil.AuxDataLayoutGetRef, AuxDataObjectType.Linemap: _tecutil.AuxDataLineMapGetRef, AuxDataObjectType.Page: _tecutil.AuxDataPageGetRef, AuxDataObjectType.Variable: _tecutil.AuxDataVarGetRef, AuxDataObjectType.Zone: _tecutil.AuxDataZoneGetRef} with self._activated_parent(): return _dispatch[self.object_type](*self.getref_args) @contextmanager def _activated_parent(self): if self.parent: with self.parent.activated(): yield else: yield @contextmanager def assignment(self): _tecutil.AuxDataBeginAssign() try: yield finally: _tecutil.AuxDataEndAssign()
[docs] def index(self, key): """Returns the zero-based index of the element based on key. Example usage:: >>> frame = tp.active_frame() >>> frame.aux_data['result'] = '3.1415' >>> frame.aux_data['other_info'] = '128' >>> print(frame.aux_data.index('other_info')) 0 >>> print(frame.aux_data.index('result')) 1 """ try: success, index = _tecutil.AuxDataGetItemIndex(self, key) index -= 1 if not success: raise TecplotKeyError except TecplotSystemError: raise TecplotKeyError return index
_Item = namedtuple('Item', ['key', 'value', 'dtype', 'retain']) def _item(self, index): res =_tecutil.AuxDataGetItemByIndex(self, index + 1) key, value, dtype, retain = res if dtype is AuxDataType.String: value = ctypes.cast(value, ctypes.c_char_p).value.decode('utf-8') else: # if we ever add another type to AuxDataType, this would # need to be expanded as well as setitem which currently # just converts every input to a string. raise TecplotNotImplementedError return AuxData._Item(key, value, dtype, retain)
[docs] def key(self, index): """Returns the key at a specific zero-based index. Example usage:: >>> frame = tp.active_frame() >>> frame.aux_data['result'] = '3.1415' >>> frame.aux_data['other_info'] = '128' >>> print(frame.aux_data.key(0)) other_info >>> print(frame.aux_data.key(1)) result """ return self._item(index).key
def __getitem__(self, key): if isinstance(key, str): key = self.index(key) return self._item(key).value @lock() def __setitem__(self, key, value): if isinstance(key, int): try: key = self.key(key) except: raise TecplotIndexError if not _tecutil.AuxDataSetItem(self, key, str(value), AuxDataType.String.value, True): raise TecplotSystemError() @lock() def __delitem__(self, key): if isinstance(key, str): key = self.index(key) _tecutil.AuxDataDeleteItemByIndex(self, key + 1) def __len__(self): return _tecutil.AuxDataGetNumItems(self) def __iter__(self): self._current_index = -1 self._current_length = len(self) return self def __next__(self): self._current_index += 1 if self._current_index < self._current_length: return self.key(self._current_index) else: raise StopIteration def next(self): return self.__next__()
[docs] def items(self): """Yields all key/value pairs of the Aux Data attached to the parent. Elements are always ordered alphabetically by the keys. Example usage:: >>> frame = tp.active_frame() >>> frame.aux_data['result'] = '3.1415' >>> frame.aux_data['other_info'] = '128' >>> for key, value in frame.aux_data.items(): ... print(key, value) other_info 128 result 3.1415 """ for i in range(len(self)): item = self._item(i) yield item.key, item.value
[docs] def keys(self): """Yields all keys of the Aux Data attached to the parent. Elements are always ordered alphabetically by the keys. Example usage:: >>> frame = tp.active_frame() >>> frame.aux_data['result'] = '3.1415' >>> frame.aux_data['other_info'] = '128' >>> for value in frame.aux_data.keys(): ... print(value) other_info result """ for key in self: yield key
[docs] def values(self): """Yields all values of the Aux Data attached to the parent. Elements are always ordered alphabetically by the keys. Example usage:: >>> frame = tp.active_frame() >>> frame.aux_data['result'] = '3.1415' >>> frame.aux_data['other_info'] = '128' >>> for value in frame.aux_data.values(): ... print(value) 128 3.1415 """ for _, value in self.items(): yield value
[docs] def as_dict(self): """Returns a Python dict of the Aux Data attached to the parent. Note that this will remove the alphabetical ordering guarantee that Aux Data has since Python dict objects are unordered. Example usage:: >>> frame = tp.active_frame() >>> frame.aux_data['result'] = '3.1415' >>> frame.aux_data['other_info'] = '128' >>> aux = frame.aux_data.as_dict() >>> print(aux) {'result': '3.1415', 'other_info': '128'} """ return {k: v for k, v in self.items()}
def __str__(self): return str(self.as_dict())
[docs] def update(self, *other, **kwargs): """Update Aux Data with key/value pairs from another Aux Data or dict. Example usage:: >>> frame = tp.active_frame() >>> frame.aux_data.update({'result': '3.1415', 'other_info': '128'}) >>> print(frame.aux_data) {'result': '3.1415', 'other_info': '128'} """ with self.assignment(): for d in it.chain(other, [kwargs]): for k, v in d.items(): self[k] = v
[docs] def clear(self): """Deletes all Aux Data from the associated object. Example usage:: >>> print(frame.aux_data) {'bb': 'test bb', 'cc': 'test cc', 'aa': 'test aa'} >>> frame.aux_data.clear() >>> print(frame.aux_data) {} """ for key in list(self.keys()): del self[key]