3
# This file is part of Diamond.
5
# Diamond is free software: you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation, either version 3 of the License, or
8
# (at your option) any later version.
10
# Diamond is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with Diamond. If not, see <http://www.gnu.org/licenses/>.
21
def __init__(self, parent, child):
23
The .doc and .attrs comes from parent, and the .data comes from child. This
24
is used to hide integer_value etc. from the left hand side, but for its data
25
entry to show up on the right.
31
self.name = parent.name
32
self.schemaname = parent.schemaname
33
self.attrs = self.parent.attrs
34
self.children = parent.children
35
self.datatype = child.datatype
36
self.data = child.data
38
self.active = parent.active
42
def set_attr(self, attr, val):
43
self.parent.set_attr(attr, val)
47
def get_attr(self, attr):
48
return self.parent.get_attr(attr)
50
def set_data(self, data):
51
self.child.set_data(data)
52
self.datatype = self.child.datatype
53
self.data = self.child.data
57
def valid_data(self, datatype, data):
58
return self.child.valid_data(datatype, data)
60
def validity_check(self, datatype, data):
61
return self.child.validity_check(datatype, data)
63
def matches(self, text, case_sensitive = False):
64
old_parent_data = self.parent.data
65
self.parent.data = None
66
parent_matches = self.parent.matches(text, case_sensitive)
67
self.parent.data = old_parent_data
73
text_re = re.compile(text)
75
text_re = re.compile(text, re.IGNORECASE)
77
if not self.child.data is None and not text_re.search(self.child.data) is None:
83
return self.parent.is_comment()
85
def get_comment(self):
86
return self.parent.get_comment()
88
def is_tensor(self, geometry_dim_tree):
90
Perform a series of tests on the current MixedTree, to determine if
91
it is intended to be used to store tensor or vector data.
94
# Check that a geometry is defined
95
if geometry_dim_tree is None:
98
# Check that this element has calculable and positive dimensions
100
dim1, dim2 = self.tensor_shape(geometry_dim_tree)
103
except AssertionError:
106
# The element must have dim1, rank and shape attributes
107
if "dim1" not in self.child.attrs.keys() \
108
or "rank" not in self.child.attrs.keys() \
109
or "shape" not in self.child.attrs.keys():
112
# The dim1 and rank attributes must be of fixed type
113
if self.child.attrs["dim1"][0] != "fixed" or self.child.attrs["rank"][0] != "fixed":
116
if "dim2" in self.child.attrs.keys():
117
# If a dim2 attribute is specified, it must be of fixed type and the rank must be 2
118
# Also, the shape attribute must be a list of integers with cardinality equal to the rank
119
if self.child.attrs["dim2"][0] != "fixed" \
120
or self.child.attrs["rank"][1] != "2" \
121
or not isinstance(self.child.attrs["shape"][0], plist.List) \
122
or self.child.attrs["shape"][0].datatype is not int \
123
or str(self.child.attrs["shape"][0].cardinality) != self.child.attrs["rank"][1]:
126
# Otherwise, the rank must be one and the shape an integer
127
elif self.child.attrs["rank"][1] != "1" or self.child.attrs["shape"][0] is not int:
130
# The data for the element must be a list of one or more
131
if not isinstance(self.datatype, plist.List) or self.datatype.cardinality != "+":
134
# If the shape has been set, check that it has a valid value
135
if self.child.attrs["shape"][1] != None:
136
if geometry_dim_tree.data is None:
139
dim1, dim2 = self.tensor_shape(geometry_dim_tree)
140
if "dim2" in self.child.attrs.keys():
141
if self.child.attrs["shape"][1] != str(dim1) + " " + str(dim2):
143
elif self.child.attrs["shape"][1] != str(dim1):
148
def tensor_shape(self, dimension):
150
Read the tensor shape for tensor or vector data in the current MixedTree.
153
if not isinstance(dimension, int):
154
dimension = int(dimension.data)
158
if "dim1" in self.child.attrs.keys():
159
dim1 = int(eval(self.child.attrs["dim1"][1], {"dim":dimension}))
160
if "dim2" in self.child.attrs.keys():
161
dim2 = int(eval(self.child.attrs["dim2"][1], {"dim":dimension}))
165
def is_symmetric_tensor(self, geometry):
167
Read if the tensor data in the current MixedTree is symmetric.
170
dim1, dim2 = self.tensor_shape(geometry)
172
return dim1 == dim2 and "symmetric" in self.child.attrs.keys() and self.child.attrs["symmetric"][1] == "true"
174
def is_python_code(self):
176
Perform a series of tests on the current MixedTree, to determine if
177
it is intended to be used to store python code data.
181
lang = self.get_attr("language")
187
if self.datatype is not str:
190
if "type" in self.child.attrs.keys():
191
return self.child.attrs["type"][1] == "python"
195
def get_name_path(self, leaf = True):
196
return self.parent.get_name_path(leaf)
198
def is_sliceable(self):