Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion source/wrappers/python/pyuda/_dim.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from __future__ import (division, print_function, absolute_import)

import copy

class Dim(object):

Expand All @@ -20,3 +20,18 @@ def units(self):

def __repr__(self):
return "<Dim: {0}>".format(self.label) if self.label else "<Dim>"

def __deepcopy__(self, memo):
return DataOwningDim(data=copy.deepcopy(self.data, memo),
label=copy.deepcopy(self.label, memo),
units=copy.deepcopy(self.units, memo))


class DataOwningDim:
def __init__(self, data=None, label='', units=''):
self.data = data
self.label = label
self.units = units

def __repr__(self):
return "<Dim: {0}>".format(self.label) if self.label else "<Dim>"
105 changes: 85 additions & 20 deletions source/wrappers/python/pyuda/_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import json
import base64
import numpy as np
import copy

import cpyuda

Expand Down Expand Up @@ -59,7 +60,28 @@ def default(self, obj):
return super().default(obj)


class Signal(Data):
class SignalDataImpl(Data):
def plot(self):
import matplotlib.pyplot as plt

dim = self.dims[0]

plt.plot(dim.data, self.data)
plt.xlabel('{0} ({1})'.format(dim.label, dim.units))
plt.ylabel('{0} ({1})'.format(self.label, self.units))
plt.show()

def widget(self):
raise NotImplementedError("widget function not implemented for Signal objects")

def jsonify(self, indent=None):
return json.dumps(self, cls=SignalEncoder, indent=indent)

def __repr__(self):
return "<Signal: {0}>".format(self.label) if self.label else "<Signal>"


class Signal(SignalDataImpl):

def __init__(self, cresult):
self._cresult = cresult
Expand Down Expand Up @@ -202,22 +224,65 @@ def set_time_last(self):
if self.time_index == 0:
self.reverse_dimension_order()

def plot(self):
import matplotlib.pyplot as plt

dim = self.dims[0]

plt.plot(dim.data, self.data)
plt.xlabel('{0} ({1})'.format(dim.label, dim.units))
plt.ylabel('{0} ({1})'.format(self.label, self.units))
plt.show()

def widget(self):
raise NotImplementedError("widget function not implemented for Signal objects")

def jsonify(self, indent=None):
return json.dumps(self, cls=SignalEncoder, indent=indent)

def __repr__(self):
return "<Signal: {0}>".format(self.label) if self.label else "<Signal>"

def clone(self):
"""
Copy all signal data from cpyuda into a DataOwningSignal object
"""
return copy.deepcopy(self)

def __deepcopy__(self, memo):
"""
Copy all signal data from cpyuda into a DataOwningSignal object
"""
return DataOwningSignal(data=copy.deepcopy(self.data, memo),
errors=copy.deepcopy(self.errors, memo),
label=copy.deepcopy(self.label, memo),
units=copy.deepcopy(self.units, memo),
description=copy.deepcopy(self.description, memo),
rank=copy.deepcopy(self.rank, memo),
dims=copy.deepcopy(self.dims, memo),
shape=copy.deepcopy(self.shape, memo),
time_index=copy.deepcopy(self.time_index, memo),
meta=copy.deepcopy(self.meta, memo))

def __reduce__(self):
"""
Overwriting __reduce__ method for pickling pyuda signal objects.
This does deep copies of all the data views held by a signal object
and constructs a data owning signal object which is picklable and can
be loaded from disk without state initialisation errors in cpyuda.
"""
return (DataOwningSignal, (copy.deepcopy(self.data),
copy.deepcopy(self.errors),
copy.deepcopy(self.label),
copy.deepcopy(self.units),
copy.deepcopy(self.description),
copy.deepcopy(self.rank),
copy.deepcopy(self.dims),
copy.deepcopy(self.shape),
copy.deepcopy(self.time_index),
copy.deepcopy(self.meta)))


class DataOwningSignal(SignalDataImpl):
"""
Class to hold a copy of a pyuda Signal object where all data arrays are owned
by the object instead of being views of memory held by the uda c-library
"""

def __init__(self, data=None, errors=None, label='', units='', description='',
rank=None, dims=None, shape=None, time_index=None, meta=None):
self.data = data
self.errors = errors
self.label = label
self.units = units
self.descritpion = description
self.rank = rank
self.dims = dims
self.shape = shape
self.time_index = time_index
self.meta = meta
if self.time_index is not None:
self.time = self.dims[self.time_index]
else:
self.time = None
52 changes: 39 additions & 13 deletions source/wrappers/python/pyuda/_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,11 @@
from ._utils import cdata_to_numpy_array
from ._data import Data

import copy
import json


class String(Data):

def __init__(self, cresult):
self._cresult = cresult
self._data = None

@property
def str(self):
if self._data is None:
self._data = self._cresult.data()
return self._data

class StringDataImpl(Data):
def __str__(self):
return self.str

Expand All @@ -35,4 +25,40 @@ def jsonify(self, indent=None):
'value': self.str
},
}
return json.dumps(obj, indent=indent)
return json.dumps(obj, indent=indent)


class String(StringDataImpl):

def __init__(self, cresult):
self._cresult = cresult
self._data = None

@property
def str(self):
if self._data is None:
self._data = self._cresult.data()
return self._data

def clone(self):
return copy.deepcopy(self)

def __deepcopy__(self, memo):
"""
Copy all signal data from cpyuda into a DataOwningString object
"""
return DataOwningString(str=copy.deepcopy(self.str, memo))

def __reduce__(self):
"""
Overwriting __reduce__ method for pickling pyuda string signal objects.
This does deep copies of all the data views held by a signal object
and constructs a data owning object which is picklable and can
be loaded from disk without state initialisation errors in cpyuda.
"""
return (DataOwningString, (copy.deepcopy(self.str),))


class DataOwningString(StringDataImpl):
def __init__(self, str=None):
self.str = str
140 changes: 92 additions & 48 deletions source/wrappers/python/pyuda/_structured.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from ._utils import (cdata_scalar_to_value, cdata_vector_to_value, cdata_array_to_value)
from ._data import Data

import copy
import json
import itertools
import numpy as np
Expand Down Expand Up @@ -32,40 +33,36 @@ def default(self, obj):
return super().default(obj)


class StructuredData(Data):
class StructuredDataImpl(Data):
def __repr__(self):
return "<Structured Data: {0}>".format(self.name)

_translation_table = None
def plot(self):
raise NotImplementedError("plot function not implemented for StructuredData objects")

def __init__(self, cnode):
self._cnode = cnode
self._children = None
self._name = self._cnode.name() or 'ROOT'
self._imported_attrs = []
if StructuredData._translation_table is None:
StructuredData._setup_translation_table()
self._import_data()
def widget(self):
raise NotImplementedError("widget function not implemented for StructuredData objects")

@classmethod
def _setup_translation_table(cls):
cls._translation_table = ''.join(chr(i) for i in range(256))
identifier_chars = tuple(itertools.chain(range(ord('0'), ord('9')+1),
range(ord('a'), ord('z')+1),
range(ord('A'), ord('Z')+1)))
identifier_chars += ('_',)
cls._translation_table = u''.join(c if ord(c) in identifier_chars else '_' for c in cls._translation_table)
def _todict(self):
obj = {}
for name in self._imported_attrs:
obj[name] = getattr(self, name)
if len(self.children) > 0:
obj['children'] = []
for child in self.children:
obj['children'].append(child._todict())
return obj

def jsonify(self, indent=None):
obj = self._todict()
return json.dumps(obj, cls=StructuredDataEncoder, indent=indent)

def _import_data(self):
data = self._cnode.data()
for (name, value) in data.items():
if value is not None:
attr_name = self._check_name(name)
self._imported_attrs.append(attr_name)
setattr(self, attr_name, value)

class TreeDisplayer:
def _display(self, depth, level):
if depth is not None and level > depth:
return
print(('|' * level + '['), self._name, ']')
print(('|' * level + '['), self.name, ']')
for name in self._imported_attrs:
print(('|' * (level + 1) + '->'), name)
for child in self.children:
Expand All @@ -92,6 +89,37 @@ def __getitem__(self, item):
else:
return [child["/".join(tokens[1:])] for child in found]


class StructuredData(StructuredDataImpl, TreeDisplayer):

_translation_table = None

def __init__(self, cnode):
self._cnode = cnode
self._children = None
self._name = self._cnode.name() or 'ROOT'
self._imported_attrs = []
if StructuredData._translation_table is None:
StructuredData._setup_translation_table()
self._import_data()

@classmethod
def _setup_translation_table(cls):
cls._translation_table = ''.join(chr(i) for i in range(256))
identifier_chars = tuple(itertools.chain(range(ord('0'), ord('9')+1),
range(ord('a'), ord('z')+1),
range(ord('A'), ord('Z')+1)))
identifier_chars += ('_',)
cls._translation_table = u''.join(c if ord(c) in identifier_chars else '_' for c in cls._translation_table)

def _import_data(self):
data = self._cnode.data()
for (name, value) in data.items():
if value is not None:
attr_name = self._check_name(name)
self._imported_attrs.append(attr_name)
setattr(self, attr_name, value)

@property
def children(self):
if self._children is None:
Expand All @@ -118,25 +146,41 @@ def _check_name(self, name):
name += '_'
return name

def __repr__(self):
return "<Structured Data: {0}>".format(self._name)

def plot(self):
raise NotImplementedError("plot function not implemented for StructuredData objects")

def widget(self):
raise NotImplementedError("widget function not implemented for StructuredData objects")

def _todict(self):
obj = {}
for name in self._imported_attrs:
obj[name] = getattr(self, name)
if len(self.children) > 0:
obj['children'] = []
for child in self.children:
obj['children'].append(child._todict())
return obj

def jsonify(self, indent=None):
obj = self._todict()
return json.dumps(obj, cls=StructuredDataEncoder, indent=indent)
def clone(self):
"""
Copy all signal data from cpyuda into a DataOwningSignal object
"""
return copy.deepcopy(self)

def __deepcopy__(self, memo):
"""
Copy all signal data from cpyuda into a DataOwningSignal object
"""
imported_attrs = {attr: copy.deepcopy(getattr(self, attr), memo)
for attr in self._imported_attrs}

return DataOwningStructuredData(children=copy.deepcopy(self.children, memo),
name=copy.deepcopy(self.name, memo),
imported_attrs=imported_attrs)

def __reduce__(self):
"""
Overwriting __reduce__ method for pickling pyuda signal objects.
This does deep copies of all the data views held by a signal object
and constructs a data owning signal object which is picklable and can
be loaded from disk without state initialisation errors in cpyuda.
"""
imported_attrs = {attr: copy.deepcopy(getattr(self, attr))
for attr in self._imported_attrs}
return (DataOwningStructuredData, (copy.deepcopy(self.children),
copy.deepcopy(self.name),
imported_attrs))


class DataOwningStructuredData(StructuredDataImpl, TreeDisplayer):
def __init__(self, children=None, name=None, imported_attrs=None):
self.children = children
self.name = name
if imported_attrs is not None:
for key, val in imported_attrs.items():
setattr(self, key, val)
Loading
Loading