nxswriter 3.12.0__py3-none-any.whl → 3.14.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nxswriter/EAttribute.py +18 -0
- nxswriter/EField.py +18 -2
- nxswriter/EVirtualField.py +718 -0
- nxswriter/FElement.py +6 -3
- nxswriter/H5Elements.py +168 -4
- nxswriter/NexusXMLHandler.py +8 -3
- nxswriter/Release.py +1 -1
- nxswriter/TangoDataWriter.py +15 -3
- {nxswriter-3.12.0.dist-info → nxswriter-3.14.0.dist-info}/METADATA +4 -4
- {nxswriter-3.12.0.dist-info → nxswriter-3.14.0.dist-info}/RECORD +14 -13
- {nxswriter-3.12.0.data → nxswriter-3.14.0.data}/scripts/NXSDataWriter +0 -0
- {nxswriter-3.12.0.data → nxswriter-3.14.0.data}/scripts/nxsfromxml +0 -0
- {nxswriter-3.12.0.dist-info → nxswriter-3.14.0.dist-info}/WHEEL +0 -0
- {nxswriter-3.12.0.dist-info → nxswriter-3.14.0.dist-info}/top_level.txt +0 -0
nxswriter/EAttribute.py
CHANGED
|
@@ -57,6 +57,24 @@ class EAttribute(FElement):
|
|
|
57
57
|
#: (:obj:`str`) trigger for asynchronous writting
|
|
58
58
|
self.trigger = None
|
|
59
59
|
|
|
60
|
+
def setRank(self, rank):
|
|
61
|
+
""" sets dimension rank
|
|
62
|
+
|
|
63
|
+
:param index: dimension rank
|
|
64
|
+
:type index: :obj:`src`
|
|
65
|
+
"""
|
|
66
|
+
self.rank = rank
|
|
67
|
+
|
|
68
|
+
def setLength(self, index, value):
|
|
69
|
+
""" sets lengths dict element
|
|
70
|
+
|
|
71
|
+
:param index: length index
|
|
72
|
+
:type index: :obj:`int`
|
|
73
|
+
:param value: length value
|
|
74
|
+
:type value: :obj:`int` or :obj:`str`
|
|
75
|
+
"""
|
|
76
|
+
self.lengths[index] = value
|
|
77
|
+
|
|
60
78
|
def store(self, xml=None, globalJSON=None):
|
|
61
79
|
""" stores the tag content
|
|
62
80
|
|
nxswriter/EField.py
CHANGED
|
@@ -81,8 +81,6 @@ class EField(FElementWithAttr):
|
|
|
81
81
|
self.shuffle = True
|
|
82
82
|
#: (:obj:`bool`) grew flag
|
|
83
83
|
self.__grew = True
|
|
84
|
-
#: (:obj:`str`) data format
|
|
85
|
-
self.__format = ''
|
|
86
84
|
|
|
87
85
|
def __isgrowing(self):
|
|
88
86
|
""" checks if it is growing in extra dimension
|
|
@@ -117,6 +115,24 @@ class EField(FElementWithAttr):
|
|
|
117
115
|
|
|
118
116
|
raise XMLSettingSyntaxError("Field without a name")
|
|
119
117
|
|
|
118
|
+
def setRank(self, rank):
|
|
119
|
+
""" sets dimension rank
|
|
120
|
+
|
|
121
|
+
:param index: dimension rank
|
|
122
|
+
:type index: :obj:`src`
|
|
123
|
+
"""
|
|
124
|
+
self.rank = rank
|
|
125
|
+
|
|
126
|
+
def setLength(self, index, value):
|
|
127
|
+
""" sets lengths dict element
|
|
128
|
+
|
|
129
|
+
:param index: length index
|
|
130
|
+
:type index: :obj:`int`
|
|
131
|
+
:param value: length value
|
|
132
|
+
:type value: :obj:`int` or :obj:`str`
|
|
133
|
+
"""
|
|
134
|
+
self.lengths[index] = value
|
|
135
|
+
|
|
120
136
|
def __getShape(self):
|
|
121
137
|
""" provides shape
|
|
122
138
|
|
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# This file is part of nexdatas - Tango Server for NeXus data writer
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2012-2017 DESY, Jan Kotanski <jkotan@mail.desy.de>
|
|
5
|
+
#
|
|
6
|
+
# nexdatas is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# nexdatas is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with nexdatas. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
""" Definitions of field tag evaluation classes """
|
|
21
|
+
|
|
22
|
+
import sys
|
|
23
|
+
|
|
24
|
+
# import numpy
|
|
25
|
+
import json
|
|
26
|
+
|
|
27
|
+
from .DataHolder import DataHolder
|
|
28
|
+
from .Element import Element
|
|
29
|
+
from .FElement import FElementWithAttr
|
|
30
|
+
from .Types import NTP
|
|
31
|
+
from .Errors import (XMLSettingSyntaxError)
|
|
32
|
+
|
|
33
|
+
from nxstools import filewriter as FileWriter
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class EVirtualSourceView(Element):
|
|
37
|
+
|
|
38
|
+
""" virtual source view tag element
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, attrs, last, streams=None):
|
|
42
|
+
""" constructor
|
|
43
|
+
|
|
44
|
+
:param attrs: dictionary of the tag attributes
|
|
45
|
+
:type attrs: :obj:`dict` <:obj:`str`, :obj:`str`>
|
|
46
|
+
:param last: the last element from the stack
|
|
47
|
+
:type last: :class:`nxswriter.Element.Element`
|
|
48
|
+
:param streams: tango-like steamset class
|
|
49
|
+
:type streams: :class:`StreamSet` or :class:`tango.LatestDeviceImpl`
|
|
50
|
+
"""
|
|
51
|
+
Element.__init__(self, "sourceview", attrs, last, streams=streams)
|
|
52
|
+
#: (:obj:`list` <:obj:`str`>) tag content
|
|
53
|
+
self.content = []
|
|
54
|
+
|
|
55
|
+
def setRank(self, rank):
|
|
56
|
+
""" sets dimension rank
|
|
57
|
+
|
|
58
|
+
:param index: dimension rank
|
|
59
|
+
:type index: :obj:`src`
|
|
60
|
+
"""
|
|
61
|
+
self.last.setSourceRank(rank)
|
|
62
|
+
|
|
63
|
+
def setLength(self, index, value):
|
|
64
|
+
""" sets lengths dict element
|
|
65
|
+
|
|
66
|
+
:param index: length index
|
|
67
|
+
:type index: :obj:`int`
|
|
68
|
+
:param value: length value
|
|
69
|
+
:type value: :obj:`int` or :obj:`str`
|
|
70
|
+
"""
|
|
71
|
+
self.last.setSourceLength(index, value)
|
|
72
|
+
|
|
73
|
+
def setSelection(self, index, value):
|
|
74
|
+
""" sets selection dict element
|
|
75
|
+
|
|
76
|
+
:param index: selection index
|
|
77
|
+
:type index: :obj:`int`
|
|
78
|
+
:param value: selection value
|
|
79
|
+
:type value: :obj:`int` or :obj:`str`
|
|
80
|
+
"""
|
|
81
|
+
self.last.setSourceSelection(index, value)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class EVirtualDataMap(Element):
|
|
85
|
+
|
|
86
|
+
""" layout map tag element
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
def __init__(self, attrs, last, streams=None):
|
|
90
|
+
""" constructor
|
|
91
|
+
|
|
92
|
+
:param attrs: dictionary of the tag attributes
|
|
93
|
+
:type attrs: :obj:`dict` <:obj:`str`, :obj:`str`>
|
|
94
|
+
:param last: the last element from the stack
|
|
95
|
+
:type last: :class:`nxswriter.Element.Element`
|
|
96
|
+
:param streams: tango-like steamset class
|
|
97
|
+
:type streams: :class:`StreamSet` or :class:`tango.LatestDeviceImpl`
|
|
98
|
+
"""
|
|
99
|
+
Element.__init__(self, "map", attrs, last, streams=streams)
|
|
100
|
+
#: (:obj:`str`) rank of the field
|
|
101
|
+
self.rank = "0"
|
|
102
|
+
#: (:obj:`str`) rank of the source field view
|
|
103
|
+
self.srcrank = "0"
|
|
104
|
+
#: (:obj:`dict` <:obj:`str`, :obj:`str`>) \
|
|
105
|
+
#: shape of the field, i.e. {index: length}
|
|
106
|
+
self.lengths = {}
|
|
107
|
+
#: (:obj:`dict` <:obj:`str`, :obj:`str`>) \
|
|
108
|
+
#: selection of the field, i.e. {index: slice or hyperslab}
|
|
109
|
+
self.selection = {}
|
|
110
|
+
#: (:obj:`dict` <:obj:`str`, :obj:`str`>) \
|
|
111
|
+
#: shape of the source field, i.e. {index: length}
|
|
112
|
+
self.srclengths = {}
|
|
113
|
+
#: (:obj:`dict` <:obj:`str`, :obj:`str`>) \
|
|
114
|
+
#: source selection of the field,
|
|
115
|
+
#: i.e. {index: slice or hyperslab}
|
|
116
|
+
self.srcselection = {}
|
|
117
|
+
#: (:obj:`list` <:obj:`str`>) tag content
|
|
118
|
+
self.content = []
|
|
119
|
+
#: (:class:`nxswriter.DataSources.DataSource`) data source
|
|
120
|
+
self.source = None
|
|
121
|
+
#: (:obj:`str`) strategy, i.e. INIT, STEP, FINAL
|
|
122
|
+
self.strategy = 'STEP'
|
|
123
|
+
#: (:obj:`str`) trigger for asynchronous writting
|
|
124
|
+
self.trigger = None
|
|
125
|
+
self.error = ""
|
|
126
|
+
# virtual layout map
|
|
127
|
+
self.__vmap = {}
|
|
128
|
+
|
|
129
|
+
def setLength(self, index, value):
|
|
130
|
+
""" sets lengths dict element
|
|
131
|
+
|
|
132
|
+
:param index: length index
|
|
133
|
+
:type index: :obj:`int`
|
|
134
|
+
:param value: length value
|
|
135
|
+
:type value: :obj:`int` or :obj:`str`
|
|
136
|
+
"""
|
|
137
|
+
self.lengths[index] = value
|
|
138
|
+
|
|
139
|
+
def setRank(self, rank):
|
|
140
|
+
""" sets dimension rank
|
|
141
|
+
|
|
142
|
+
:param index: dimension rank
|
|
143
|
+
:type index: :obj:`src`
|
|
144
|
+
"""
|
|
145
|
+
self.rank = rank
|
|
146
|
+
|
|
147
|
+
def setSourceRank(self, rank):
|
|
148
|
+
""" sets dimension rank
|
|
149
|
+
|
|
150
|
+
:param index: dimension rank
|
|
151
|
+
:type index: :obj:`src`
|
|
152
|
+
"""
|
|
153
|
+
self.srcrank = rank
|
|
154
|
+
|
|
155
|
+
def setSelection(self, index, value):
|
|
156
|
+
""" sets selection dict element
|
|
157
|
+
|
|
158
|
+
:param index: selection index
|
|
159
|
+
:type index: :obj:`int`
|
|
160
|
+
:param value: selection value
|
|
161
|
+
:type value: :obj:`int` or :obj:`str`
|
|
162
|
+
"""
|
|
163
|
+
self.selection[index] = value
|
|
164
|
+
|
|
165
|
+
def setSourceLength(self, index, value):
|
|
166
|
+
""" sets source lengths dict element
|
|
167
|
+
|
|
168
|
+
:param index: length index
|
|
169
|
+
:type index: :obj:`int`
|
|
170
|
+
:param value: length value
|
|
171
|
+
:type value: :obj:`int` or :obj:`str`
|
|
172
|
+
"""
|
|
173
|
+
self.srclengths[index] = value
|
|
174
|
+
|
|
175
|
+
def setSourceSelection(self, index, value):
|
|
176
|
+
""" sets source selection dict element
|
|
177
|
+
|
|
178
|
+
:param index: selection index
|
|
179
|
+
:type index: :obj:`int`
|
|
180
|
+
:param value: selection value
|
|
181
|
+
:type value: :obj:`int` or :obj:`str`
|
|
182
|
+
"""
|
|
183
|
+
self.srcselection[index] = value
|
|
184
|
+
|
|
185
|
+
def __getShape(self):
|
|
186
|
+
""" provides shape
|
|
187
|
+
|
|
188
|
+
:returns: object shape
|
|
189
|
+
:rtype: :obj:`list` <:obj:`int` >
|
|
190
|
+
"""
|
|
191
|
+
shape = []
|
|
192
|
+
try:
|
|
193
|
+
if int(self.rank) > 0:
|
|
194
|
+
for i in range(int(self.rank)):
|
|
195
|
+
si = str(i + 1)
|
|
196
|
+
if self.lengths and si in self.lengths.keys() \
|
|
197
|
+
and self.lengths[si] is not None:
|
|
198
|
+
if int(self.lengths[si]) > 0:
|
|
199
|
+
shape.append(int(self.lengths[si]))
|
|
200
|
+
else:
|
|
201
|
+
raise XMLSettingSyntaxError(
|
|
202
|
+
"Dimensions not defined")
|
|
203
|
+
if len(shape) < int(self.rank):
|
|
204
|
+
raise XMLSettingSyntaxError(
|
|
205
|
+
"Too small dimension number")
|
|
206
|
+
except XMLSettingSyntaxError:
|
|
207
|
+
if self.rank and int(self.rank) >= 0:
|
|
208
|
+
shape = [0] * (int(self.rank))
|
|
209
|
+
else:
|
|
210
|
+
shape = [0]
|
|
211
|
+
return shape
|
|
212
|
+
|
|
213
|
+
def __getKey(self):
|
|
214
|
+
""" provides key
|
|
215
|
+
|
|
216
|
+
:returns: object key
|
|
217
|
+
:rtype: :obj:`list` <:obj:`int` >
|
|
218
|
+
"""
|
|
219
|
+
key = []
|
|
220
|
+
try:
|
|
221
|
+
if int(self.rank) > 0:
|
|
222
|
+
for i in range(int(self.rank)):
|
|
223
|
+
si = str(i + 1)
|
|
224
|
+
if self.selection and si in self.selection.keys() \
|
|
225
|
+
and self.selection[si] is not None:
|
|
226
|
+
key.append(self.selection[si])
|
|
227
|
+
else:
|
|
228
|
+
key.append(None)
|
|
229
|
+
except XMLSettingSyntaxError:
|
|
230
|
+
pass
|
|
231
|
+
return key
|
|
232
|
+
|
|
233
|
+
def __getSourceShape(self):
|
|
234
|
+
""" provides source shape
|
|
235
|
+
|
|
236
|
+
:returns: object shape
|
|
237
|
+
:rtype: :obj:`list` <:obj:`int` >
|
|
238
|
+
"""
|
|
239
|
+
shape = []
|
|
240
|
+
try:
|
|
241
|
+
if int(self.srcrank) > 0:
|
|
242
|
+
for i in range(int(self.srcrank)):
|
|
243
|
+
si = str(i + 1)
|
|
244
|
+
if self.srclengths and si in self.srclengths.keys() \
|
|
245
|
+
and self.srclengths[si] is not None:
|
|
246
|
+
if int(self.srclengths[si]) > 0:
|
|
247
|
+
shape.append(int(self.srclengths[si]))
|
|
248
|
+
else:
|
|
249
|
+
raise XMLSettingSyntaxError(
|
|
250
|
+
"Dimensions not defined")
|
|
251
|
+
if len(shape) < int(self.srcrank):
|
|
252
|
+
raise XMLSettingSyntaxError(
|
|
253
|
+
"Too small dimension number")
|
|
254
|
+
except XMLSettingSyntaxError:
|
|
255
|
+
if self.srcrank and int(self.srcrank) >= 0:
|
|
256
|
+
shape = [0] * (int(self.srcrank))
|
|
257
|
+
else:
|
|
258
|
+
shape = [0]
|
|
259
|
+
return shape or None
|
|
260
|
+
|
|
261
|
+
def __getSourceKey(self):
|
|
262
|
+
""" provides source key
|
|
263
|
+
|
|
264
|
+
:returns: object key
|
|
265
|
+
:rtype: :obj:`list` <:obj:`int` >
|
|
266
|
+
"""
|
|
267
|
+
key = []
|
|
268
|
+
try:
|
|
269
|
+
if int(self.srcrank) > 0:
|
|
270
|
+
for i in range(int(self.srcrank)):
|
|
271
|
+
si = str(i + 1)
|
|
272
|
+
if self.srcselection and si in self.srcselection.keys() \
|
|
273
|
+
and self.srcselection[si] is not None:
|
|
274
|
+
key.append(self.srcselection[si])
|
|
275
|
+
else:
|
|
276
|
+
key.append(None)
|
|
277
|
+
except XMLSettingSyntaxError:
|
|
278
|
+
pass
|
|
279
|
+
return key or None
|
|
280
|
+
|
|
281
|
+
def store(self, xml=None, globalJSON=None):
|
|
282
|
+
""" stores the tag content
|
|
283
|
+
|
|
284
|
+
:param xml: xml setting
|
|
285
|
+
:type xml: :obj: `str`
|
|
286
|
+
:param globalJSON: global JSON string
|
|
287
|
+
:type globalJSON: \
|
|
288
|
+
: :obj:`dict` <:obj:`str`, :obj:`dict` <:obj:`str`, any>>
|
|
289
|
+
"""
|
|
290
|
+
|
|
291
|
+
shape = self.__getShape()
|
|
292
|
+
if shape:
|
|
293
|
+
self.__vmap["shape"] = shape
|
|
294
|
+
key = self.__getKey()
|
|
295
|
+
if key:
|
|
296
|
+
self.__vmap["key"] = key
|
|
297
|
+
srcshape = self.__getSourceShape()
|
|
298
|
+
if srcshape is not None:
|
|
299
|
+
self.__vmap["sourceshape"] = srcshape
|
|
300
|
+
srckey = self.__getSourceKey()
|
|
301
|
+
if srckey is not None:
|
|
302
|
+
self.__vmap["sourcekey"] = srckey
|
|
303
|
+
target = None
|
|
304
|
+
filename = None
|
|
305
|
+
fieldpath = None
|
|
306
|
+
if "name" in self._tagAttrs.keys():
|
|
307
|
+
self.__name = self._tagAttrs["name"]
|
|
308
|
+
if "target" in self._tagAttrs.keys():
|
|
309
|
+
if sys.version_info > (3,):
|
|
310
|
+
target = self._tagAttrs["target"]
|
|
311
|
+
else:
|
|
312
|
+
target = self._tagAttrs["target"].encode()
|
|
313
|
+
if target:
|
|
314
|
+
self.__vmap["target"] = target
|
|
315
|
+
if "filename" in self._tagAttrs.keys():
|
|
316
|
+
if sys.version_info > (3,):
|
|
317
|
+
filename = self._tagAttrs["filename"]
|
|
318
|
+
else:
|
|
319
|
+
filename = self._tagAttrs["filename"].encode()
|
|
320
|
+
if filename:
|
|
321
|
+
self.__vmap["filename"] = filename
|
|
322
|
+
if "fieldpath" in self._tagAttrs.keys():
|
|
323
|
+
if sys.version_info > (3,):
|
|
324
|
+
fieldpath = self._tagAttrs["fieldpath"]
|
|
325
|
+
else:
|
|
326
|
+
fieldpath = self._tagAttrs["fieldpath"].encode()
|
|
327
|
+
if fieldpath:
|
|
328
|
+
self.__vmap["fieldpath"] = fieldpath
|
|
329
|
+
if not self.source:
|
|
330
|
+
self.last.appendVmap(self.__vmap)
|
|
331
|
+
if self.source:
|
|
332
|
+
if self.source.isValid():
|
|
333
|
+
return self.strategy, self.trigger
|
|
334
|
+
|
|
335
|
+
def run(self):
|
|
336
|
+
""" runner
|
|
337
|
+
|
|
338
|
+
:brief: During its thread run it fetches the data from the source
|
|
339
|
+
"""
|
|
340
|
+
try:
|
|
341
|
+
if self.source:
|
|
342
|
+
dt = self.source.getData()
|
|
343
|
+
if dt and isinstance(dt, dict):
|
|
344
|
+
dh = DataHolder(streams=self._streams, **dt)
|
|
345
|
+
val = dh.cast("string")
|
|
346
|
+
self.last.appendVmap(val, self.__vmap)
|
|
347
|
+
|
|
348
|
+
except Exception:
|
|
349
|
+
info = sys.exc_info()
|
|
350
|
+
import traceback
|
|
351
|
+
message = self.setMessage(
|
|
352
|
+
str(info[1].__str__()) + "\n " + (" ").join(
|
|
353
|
+
traceback.format_tb(sys.exc_info()[2])))
|
|
354
|
+
# message = self.setMessage( sys.exc_info()[1].__str__() )
|
|
355
|
+
del info
|
|
356
|
+
#: notification of error in the run method (defined in base class)
|
|
357
|
+
self.error = message
|
|
358
|
+
# self.error = sys.exc_info()
|
|
359
|
+
finally:
|
|
360
|
+
if self.error:
|
|
361
|
+
if self._streams:
|
|
362
|
+
if self.canfail:
|
|
363
|
+
self._streams.warn(
|
|
364
|
+
"EField::run() - %s " % str(self.error))
|
|
365
|
+
else:
|
|
366
|
+
self._streams.error(
|
|
367
|
+
"EField::run() - %s " % str(self.error))
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
class EVirtualField(FElementWithAttr):
|
|
371
|
+
|
|
372
|
+
""" virtual field H5 tag element
|
|
373
|
+
"""
|
|
374
|
+
|
|
375
|
+
def __init__(self, attrs, last, streams=None,
|
|
376
|
+
reloadmode=False):
|
|
377
|
+
""" constructor
|
|
378
|
+
|
|
379
|
+
:param attrs: dictionary of the tag attributes
|
|
380
|
+
:type attrs: :obj:`dict` <:obj:`str`, :obj:`str`>
|
|
381
|
+
:param last: the last element from the stack
|
|
382
|
+
:type last: :class:`nxswriter.Element.Element`
|
|
383
|
+
:param streams: tango-like steamset class
|
|
384
|
+
:type streams: :class:`StreamSet` or :class:`tango.LatestDeviceImpl`
|
|
385
|
+
:param reloadmode: reload mode
|
|
386
|
+
:type reloadmode: :obj:`bool`
|
|
387
|
+
"""
|
|
388
|
+
FElementWithAttr.__init__(self, "vds", attrs, last, streams=streams,
|
|
389
|
+
reloadmode=reloadmode)
|
|
390
|
+
#: (:obj:`str`) rank of the field
|
|
391
|
+
self.rank = "0"
|
|
392
|
+
#: (:obj:`dict` <:obj:`str`, :obj:`str`>) \
|
|
393
|
+
#: shape of the field, i.e. {index: length}
|
|
394
|
+
self.lengths = {}
|
|
395
|
+
#: (:obj:`str`) strategy, i.e. INIT, STEP, FINAL, POSTRUN
|
|
396
|
+
self.strategy = 'FINAL'
|
|
397
|
+
#: (:obj:`str`) trigger for asynchronous writing
|
|
398
|
+
self.trigger = None
|
|
399
|
+
#: (:obj:`str`) field data type
|
|
400
|
+
self.__dtype = ""
|
|
401
|
+
#: (:obj:`str`) field name
|
|
402
|
+
self.__name = ""
|
|
403
|
+
#: (:obj:`list` <:obj:`int` >) shape
|
|
404
|
+
self.__shape = []
|
|
405
|
+
#: (:obj:`list` <:obj:`dict` >) vmap list
|
|
406
|
+
self.__vmaps = []
|
|
407
|
+
|
|
408
|
+
def setRank(self, rank):
|
|
409
|
+
""" sets dimension rank
|
|
410
|
+
|
|
411
|
+
:param index: dimension rank
|
|
412
|
+
:type index: :obj:`src`
|
|
413
|
+
"""
|
|
414
|
+
self.rank = rank
|
|
415
|
+
|
|
416
|
+
def setLength(self, index, value):
|
|
417
|
+
""" sets lengths dict element
|
|
418
|
+
|
|
419
|
+
:param index: length index
|
|
420
|
+
:type index: :obj:`int`
|
|
421
|
+
:param value: length value
|
|
422
|
+
:type value: :obj:`int` or :obj:`str`
|
|
423
|
+
"""
|
|
424
|
+
self.lengths[index] = value
|
|
425
|
+
|
|
426
|
+
def __typeAndName(self):
|
|
427
|
+
""" provides type and name of the field
|
|
428
|
+
|
|
429
|
+
:returns: (type, name) tuple
|
|
430
|
+
"""
|
|
431
|
+
if "name" in self._tagAttrs.keys():
|
|
432
|
+
nm = self._tagAttrs["name"]
|
|
433
|
+
if "type" in self._tagAttrs.keys():
|
|
434
|
+
tp = NTP.nTnp[self._tagAttrs["type"]]
|
|
435
|
+
else:
|
|
436
|
+
tp = "string"
|
|
437
|
+
return tp, nm
|
|
438
|
+
else:
|
|
439
|
+
if self._streams:
|
|
440
|
+
self._streams.error(
|
|
441
|
+
"FElement::__typeAndName() - Field without a name",
|
|
442
|
+
std=False)
|
|
443
|
+
|
|
444
|
+
raise XMLSettingSyntaxError("Field without a name")
|
|
445
|
+
|
|
446
|
+
def __getShape(self):
|
|
447
|
+
""" provides shape
|
|
448
|
+
|
|
449
|
+
:returns: object shape
|
|
450
|
+
:rtype: :obj:`list` <:obj:`int` >
|
|
451
|
+
"""
|
|
452
|
+
try:
|
|
453
|
+
shape = self._findShape(
|
|
454
|
+
self.rank, self.lengths,
|
|
455
|
+
False, 0, True, checkData=True)
|
|
456
|
+
return shape
|
|
457
|
+
except XMLSettingSyntaxError:
|
|
458
|
+
if self.rank and int(self.rank) >= 0:
|
|
459
|
+
shape = [0] * (int(self.rank))
|
|
460
|
+
else:
|
|
461
|
+
shape = [0]
|
|
462
|
+
return shape
|
|
463
|
+
|
|
464
|
+
def __setAttributes(self):
|
|
465
|
+
""" creates attributes
|
|
466
|
+
|
|
467
|
+
:brief: It creates attributes in h5Object
|
|
468
|
+
"""
|
|
469
|
+
self._setAttributes(["name"])
|
|
470
|
+
self._createAttributes()
|
|
471
|
+
|
|
472
|
+
if self.strategy == "POSTRUN":
|
|
473
|
+
if sys.version_info > (3,):
|
|
474
|
+
self.h5Object.attributes.create(
|
|
475
|
+
"postrun",
|
|
476
|
+
"string", overwrite=True)[...] \
|
|
477
|
+
= self.postrun.strip()
|
|
478
|
+
else:
|
|
479
|
+
self.h5Object.attributes.create(
|
|
480
|
+
"postrun".encode(),
|
|
481
|
+
"string".encode(), overwrite=True)[...] \
|
|
482
|
+
= self.postrun.encode().strip()
|
|
483
|
+
|
|
484
|
+
def __setStrategy(self, name):
|
|
485
|
+
""" provides strategy or fill the value in
|
|
486
|
+
|
|
487
|
+
:param name: object name
|
|
488
|
+
:returns: strategy or strategy,trigger it trigger defined
|
|
489
|
+
"""
|
|
490
|
+
if self.source:
|
|
491
|
+
if self.source.isValid():
|
|
492
|
+
return self.strategy, self.trigger
|
|
493
|
+
if sys.version_info > (3,):
|
|
494
|
+
val = ("".join(self.content)).strip()
|
|
495
|
+
else:
|
|
496
|
+
val = ("".join(self.content)).strip().encode()
|
|
497
|
+
if val:
|
|
498
|
+
lval = val.split("\n")
|
|
499
|
+
for el in lval:
|
|
500
|
+
if el.strip():
|
|
501
|
+
self.__vmaps.append({"target": el.strip()})
|
|
502
|
+
return self.strategy, self.trigger
|
|
503
|
+
|
|
504
|
+
def store(self, xml=None, globalJSON=None):
|
|
505
|
+
""" stores the tag content
|
|
506
|
+
|
|
507
|
+
:param xml: xml setting
|
|
508
|
+
:type xml: :obj:`str`
|
|
509
|
+
:param globalJSON: global JSON string
|
|
510
|
+
:type globalJSON: \
|
|
511
|
+
: :obj:`dict` <:obj:`str`, :obj:`dict` <:obj:`str`, any>>
|
|
512
|
+
:returns: (strategy, trigger)
|
|
513
|
+
:rtype: (:obj:`str`, :obj:`str`)
|
|
514
|
+
"""
|
|
515
|
+
|
|
516
|
+
# type and name
|
|
517
|
+
self.__dtype, self.__name = self.__typeAndName()
|
|
518
|
+
# shape
|
|
519
|
+
self.__shape = self.__getShape()
|
|
520
|
+
return self.__setStrategy(self.__name)
|
|
521
|
+
|
|
522
|
+
def __cureKeys(self, key):
|
|
523
|
+
tkey = []
|
|
524
|
+
if isinstance(key, list):
|
|
525
|
+
try:
|
|
526
|
+
sk = list(set([len(ky) for ky in key]))
|
|
527
|
+
except Exception:
|
|
528
|
+
sk = []
|
|
529
|
+
if len(sk) == 1 and sk[0] == 4:
|
|
530
|
+
offset = []
|
|
531
|
+
block = []
|
|
532
|
+
count = []
|
|
533
|
+
stride = []
|
|
534
|
+
for ky in key:
|
|
535
|
+
off, bl, cnt, std = ky
|
|
536
|
+
offset.append(off)
|
|
537
|
+
block.append(bl)
|
|
538
|
+
count.append(cnt)
|
|
539
|
+
stride.append(std)
|
|
540
|
+
return FileWriter.FTHyperslab(offset, block, count, stride)
|
|
541
|
+
for ky in key:
|
|
542
|
+
if isinstance(ky, list) and len(ky) > 0 and len(ky) < 4:
|
|
543
|
+
tkey.append(slice(*ky))
|
|
544
|
+
else:
|
|
545
|
+
if ky is None:
|
|
546
|
+
ky = slice(None)
|
|
547
|
+
tkey.append(ky)
|
|
548
|
+
|
|
549
|
+
return tuple(tkey)
|
|
550
|
+
return key
|
|
551
|
+
|
|
552
|
+
def appendVmap(self, values, base=None):
|
|
553
|
+
""" append virtual map items
|
|
554
|
+
|
|
555
|
+
:param values: a list of map items to append
|
|
556
|
+
:type values: :obj:`str` or :obj:`list`< :obj:`str` >
|
|
557
|
+
or :obj:`list`< :obj:`dict` >
|
|
558
|
+
:param base: base map item to append
|
|
559
|
+
:type base: :obj:`dict`
|
|
560
|
+
"""
|
|
561
|
+
if hasattr(values, "shape") and values.shape == tuple():
|
|
562
|
+
values = str(values)
|
|
563
|
+
try:
|
|
564
|
+
if isinstance(values, str):
|
|
565
|
+
values = json.loads(values)
|
|
566
|
+
if not isinstance(values, list):
|
|
567
|
+
values = [values]
|
|
568
|
+
except Exception:
|
|
569
|
+
if hasattr(values, "flatten"):
|
|
570
|
+
values = values.flatten()
|
|
571
|
+
if isinstance(values, str):
|
|
572
|
+
values = [values]
|
|
573
|
+
val = values
|
|
574
|
+
values = []
|
|
575
|
+
for vl in val:
|
|
576
|
+
try:
|
|
577
|
+
if isinstance(vl, str):
|
|
578
|
+
vl = json.loads(vl)
|
|
579
|
+
values.append(vl)
|
|
580
|
+
except Exception:
|
|
581
|
+
values.append(str(vl).strip())
|
|
582
|
+
for vl in values:
|
|
583
|
+
if isinstance(base, dict):
|
|
584
|
+
fval = dict(base)
|
|
585
|
+
else:
|
|
586
|
+
fval = {}
|
|
587
|
+
if isinstance(vl, dict):
|
|
588
|
+
fval.update(vl)
|
|
589
|
+
else:
|
|
590
|
+
fval.update({"target": vl.strip()})
|
|
591
|
+
self.__vmaps.append(fval)
|
|
592
|
+
return len(self.__vmaps)
|
|
593
|
+
|
|
594
|
+
def __findShape(self, key, eshape=None, unlimited=True):
|
|
595
|
+
if isinstance(key, FileWriter.FTHyperslab):
|
|
596
|
+
if not unlimited:
|
|
597
|
+
count = [(ct if ct != FileWriter.writer.unlimited() else 1)
|
|
598
|
+
for ct in key.count]
|
|
599
|
+
|
|
600
|
+
block = [(ct if ct != FileWriter.writer.unlimited() else 1)
|
|
601
|
+
for ct in key.block]
|
|
602
|
+
else:
|
|
603
|
+
count = key.count
|
|
604
|
+
block = key.block
|
|
605
|
+
eshape = [bl * count[hi] for hi, bl in enumerate(block)]
|
|
606
|
+
if isinstance(key, tuple):
|
|
607
|
+
eshape = []
|
|
608
|
+
for ky in key:
|
|
609
|
+
if not unlimited and ky.stop == FileWriter.writer.unlimited():
|
|
610
|
+
eshape.append(1)
|
|
611
|
+
elif isinstance(ky, slice) and ky.stop > 0:
|
|
612
|
+
start = ky.start if ky.start is not None else 0
|
|
613
|
+
step = ky.step if ky.step is not None else 1
|
|
614
|
+
eshape.append((ky.stop - start) // step)
|
|
615
|
+
else:
|
|
616
|
+
eshape.append(1)
|
|
617
|
+
return eshape
|
|
618
|
+
|
|
619
|
+
def __createVDS(self):
|
|
620
|
+
""" create the virtual field object
|
|
621
|
+
"""
|
|
622
|
+
vlf = FileWriter.virtual_field_layout(
|
|
623
|
+
self.__shape, self.__dtype)
|
|
624
|
+
counter = 0
|
|
625
|
+
for vmap in self.__vmaps:
|
|
626
|
+
fieldpath = ""
|
|
627
|
+
filename = ""
|
|
628
|
+
edtype = vmap["dtype"] \
|
|
629
|
+
if "dtype" in vmap else self.__dtype
|
|
630
|
+
key = vmap["key"] if "key" in vmap else counter
|
|
631
|
+
key = self.__cureKeys(key)
|
|
632
|
+
if "shape" in vmap:
|
|
633
|
+
eshape = vmap["shape"]
|
|
634
|
+
elif isinstance(key, int):
|
|
635
|
+
eshape = list(self.__shape)
|
|
636
|
+
eshape[0] = 1
|
|
637
|
+
else:
|
|
638
|
+
eshape = [0] * len(self.__shape)
|
|
639
|
+
fieldpath = vmap["fieldpath"] \
|
|
640
|
+
if "fieldpath" in vmap else "/data"
|
|
641
|
+
filename = vmap["filename"] if "filename" in vmap else None
|
|
642
|
+
if "target" in vmap:
|
|
643
|
+
target = vmap["target"]
|
|
644
|
+
if target.startswith("h5file:/"):
|
|
645
|
+
target = target[8:]
|
|
646
|
+
if "::" in target:
|
|
647
|
+
filename, fieldpath = target.split("::")
|
|
648
|
+
elif ":/" in target:
|
|
649
|
+
filename, fieldpath = target.split(":/")
|
|
650
|
+
else:
|
|
651
|
+
fieldpath = target
|
|
652
|
+
obj = self._lastObject()
|
|
653
|
+
while filename is None:
|
|
654
|
+
par = obj.parent
|
|
655
|
+
if par is None:
|
|
656
|
+
break
|
|
657
|
+
if hasattr(par, "root") and hasattr(par, "name"):
|
|
658
|
+
filename = par.name
|
|
659
|
+
break
|
|
660
|
+
else:
|
|
661
|
+
obj = par
|
|
662
|
+
sourceshape = vmap["sourceshape"] \
|
|
663
|
+
if "sourceshape" in vmap else None
|
|
664
|
+
sourcekey = vmap["sourcekey"] \
|
|
665
|
+
if "sourcekey" in vmap else None
|
|
666
|
+
sourcekey = self.__cureKeys(sourcekey)
|
|
667
|
+
if not any(eshape):
|
|
668
|
+
eshape = self.__findShape(key, eshape, unlimited=False)
|
|
669
|
+
ef = FileWriter.target_field_view(
|
|
670
|
+
filename, fieldpath, eshape, edtype)
|
|
671
|
+
if eshape:
|
|
672
|
+
counter += eshape[0]
|
|
673
|
+
else:
|
|
674
|
+
counter += 1
|
|
675
|
+
# print("KEY", key, sourcekey, sourceshape, eshape)
|
|
676
|
+
vlf.add(key, ef, sourcekey, sourceshape)
|
|
677
|
+
self.h5Object = self._lastObject().create_virtual_field(
|
|
678
|
+
self.__name, vlf)
|
|
679
|
+
|
|
680
|
+
def run(self):
|
|
681
|
+
""" runner
|
|
682
|
+
|
|
683
|
+
:brief: During its thread run it fetches the data from the source
|
|
684
|
+
"""
|
|
685
|
+
try:
|
|
686
|
+
if self.source:
|
|
687
|
+
dt = self.source.getData()
|
|
688
|
+
if dt and isinstance(dt, dict):
|
|
689
|
+
dh = DataHolder(streams=self._streams, **dt)
|
|
690
|
+
val = dh.cast("string")
|
|
691
|
+
self.appendVmap(val)
|
|
692
|
+
# print("VMAPS", self.__vmaps)
|
|
693
|
+
# print("SHaPE", self.__shape)
|
|
694
|
+
# print("TYPE", self.__dtype)
|
|
695
|
+
# print("NAME", self.__name)
|
|
696
|
+
if self.__vmaps and self.__shape and self.__dtype and self.__name:
|
|
697
|
+
self.__createVDS()
|
|
698
|
+
self.__setAttributes()
|
|
699
|
+
except Exception:
|
|
700
|
+
info = sys.exc_info()
|
|
701
|
+
import traceback
|
|
702
|
+
message = self.setMessage(
|
|
703
|
+
str(info[1].__str__()) + "\n " + (" ").join(
|
|
704
|
+
traceback.format_tb(sys.exc_info()[2])))
|
|
705
|
+
# message = self.setMessage( sys.exc_info()[1].__str__() )
|
|
706
|
+
del info
|
|
707
|
+
#: notification of error in the run method (defined in base class)
|
|
708
|
+
self.error = message
|
|
709
|
+
# self.error = sys.exc_info()
|
|
710
|
+
finally:
|
|
711
|
+
if self.error:
|
|
712
|
+
if self._streams:
|
|
713
|
+
if self.canfail:
|
|
714
|
+
self._streams.warn(
|
|
715
|
+
"EField::run() - %s " % str(self.error))
|
|
716
|
+
else:
|
|
717
|
+
self._streams.error(
|
|
718
|
+
"EField::run() - %s " % str(self.error))
|
nxswriter/FElement.py
CHANGED
|
@@ -195,7 +195,7 @@ class FElement(Element):
|
|
|
195
195
|
if sys.version_info > (3,):
|
|
196
196
|
val = ("".join(self.content)).strip()
|
|
197
197
|
else:
|
|
198
|
-
val = ("".join(self.content)).strip().encode()
|
|
198
|
+
val = ("".join(self.content)).strip().encode("utf8")
|
|
199
199
|
found = False
|
|
200
200
|
if checkData and self.source and self.source.isValid():
|
|
201
201
|
data = self.source.getData()
|
|
@@ -497,9 +497,12 @@ class FElementWithAttr(FElement):
|
|
|
497
497
|
ekey, "string", overwrite=True)[...] \
|
|
498
498
|
= self._tagAttrs[key].strip()
|
|
499
499
|
else:
|
|
500
|
+
try:
|
|
501
|
+
vl = self._tagAttrs[key].strip().encode()
|
|
502
|
+
except Exception:
|
|
503
|
+
vl = self._tagAttrs[key].strip().encode("utf8")
|
|
500
504
|
self.h5Object.attributes.create(
|
|
501
|
-
ekey, "string", overwrite=True)[...]
|
|
502
|
-
= self._tagAttrs[key].strip().encode()
|
|
505
|
+
ekey, "string", overwrite=True)[...] = vl
|
|
503
506
|
|
|
504
507
|
def h5Attribute(self, name):
|
|
505
508
|
""" provides attribute h5 object
|
nxswriter/H5Elements.py
CHANGED
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
|
|
20
20
|
""" Definitions of tag evaluation classes """
|
|
21
21
|
|
|
22
|
+
import json
|
|
23
|
+
|
|
22
24
|
from .Element import Element
|
|
23
25
|
from .FElement import FElement
|
|
24
26
|
from .DataHolder import DataHolder
|
|
@@ -125,7 +127,27 @@ class EDimensions(Element):
|
|
|
125
127
|
"""
|
|
126
128
|
Element.__init__(self, "dimensions", attrs, last, streams=streams)
|
|
127
129
|
if "rank" in attrs.keys():
|
|
128
|
-
self.last.
|
|
130
|
+
self.last.setRank(attrs["rank"])
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class ESelection(Element):
|
|
134
|
+
|
|
135
|
+
""" selection tag element
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
def __init__(self, attrs, last, streams=None):
|
|
139
|
+
""" constructor
|
|
140
|
+
|
|
141
|
+
:param attrs: dictionary of the tag attributes
|
|
142
|
+
:type attrs: :obj:`dict` <:obj:`str`, :obj:`str`>
|
|
143
|
+
:param last: the last element from the stack
|
|
144
|
+
:type last: :class:`nxswriter.Element.Element`
|
|
145
|
+
:param streams: tango-like steamset class
|
|
146
|
+
:type streams: :class:`StreamSet` or :class:`tango.LatestDeviceImpl`
|
|
147
|
+
"""
|
|
148
|
+
Element.__init__(self, "selection", attrs, last, streams=streams)
|
|
149
|
+
if "rank" in attrs.keys():
|
|
150
|
+
self.last.setRank(attrs["rank"])
|
|
129
151
|
|
|
130
152
|
|
|
131
153
|
class EDim(Element):
|
|
@@ -145,7 +167,147 @@ class EDim(Element):
|
|
|
145
167
|
"""
|
|
146
168
|
Element.__init__(self, "dim", attrs, last, streams=streams)
|
|
147
169
|
if ("index" in attrs.keys()) and ("value" in attrs.keys()):
|
|
148
|
-
self._beforeLast().
|
|
170
|
+
self._beforeLast().setLength(attrs["index"], attrs["value"])
|
|
171
|
+
#: (:obj:`str`) index attribute
|
|
172
|
+
self.__index = None
|
|
173
|
+
#: (:class:`nxswriter.DataSources.DataSource`) data source
|
|
174
|
+
self.source = None
|
|
175
|
+
#: (:obj:`list` <:obj:`str`>) tag content
|
|
176
|
+
self.content = []
|
|
177
|
+
if "index" in attrs.keys():
|
|
178
|
+
self.__index = attrs["index"]
|
|
179
|
+
|
|
180
|
+
def store(self, xml=None, globalJSON=None):
|
|
181
|
+
""" stores the tag content
|
|
182
|
+
|
|
183
|
+
:param xml: xml setting
|
|
184
|
+
:type xml: :obj: `str`
|
|
185
|
+
:param globalJSON: global JSON string
|
|
186
|
+
:type globalJSON: \
|
|
187
|
+
: :obj:`dict` <:obj:`str`, :obj:`dict` <:obj:`str`, any>>
|
|
188
|
+
"""
|
|
189
|
+
if self.__index is not None and self.source:
|
|
190
|
+
dt = self.source.getData()
|
|
191
|
+
if dt and isinstance(dt, dict):
|
|
192
|
+
dh = DataHolder(streams=self._streams, **dt)
|
|
193
|
+
if dh:
|
|
194
|
+
self._beforeLast().setLength(self.__index,
|
|
195
|
+
str(dh.cast("string")))
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class ESlab(Element):
|
|
199
|
+
|
|
200
|
+
""" slab tag element
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
def __init__(self, attrs, last, streams=None):
|
|
204
|
+
""" constructor
|
|
205
|
+
|
|
206
|
+
:param attrs: dictionary of the tag attributes
|
|
207
|
+
:type attrs: :obj:`dict` <:obj:`str`, :obj:`str`>
|
|
208
|
+
:param last: the last element from the stack
|
|
209
|
+
:type last: :class:`nxswriter.Element.Element`
|
|
210
|
+
:param streams: tango-like steamset class
|
|
211
|
+
:type streams: :class:`StreamSet` or :class:`tango.LatestDeviceImpl`
|
|
212
|
+
"""
|
|
213
|
+
Element.__init__(self, "slab", attrs, last, streams=streams)
|
|
214
|
+
if ("index" in attrs.keys()):
|
|
215
|
+
offset = 0
|
|
216
|
+
block = 1
|
|
217
|
+
count = 1
|
|
218
|
+
stride = 1
|
|
219
|
+
if "offset" in attrs.keys() and attrs["offset"]:
|
|
220
|
+
try:
|
|
221
|
+
offset = int(attrs["offset"])
|
|
222
|
+
except Exception:
|
|
223
|
+
pass
|
|
224
|
+
if "block" in attrs.keys() and attrs["block"]:
|
|
225
|
+
try:
|
|
226
|
+
block = int(attrs["block"])
|
|
227
|
+
except Exception:
|
|
228
|
+
pass
|
|
229
|
+
if "count" in attrs.keys() and attrs["count"]:
|
|
230
|
+
try:
|
|
231
|
+
count = int(attrs["count"])
|
|
232
|
+
except Exception:
|
|
233
|
+
pass
|
|
234
|
+
if "stride" in attrs.keys() and attrs["stride"]:
|
|
235
|
+
try:
|
|
236
|
+
stride = int(attrs["stride"])
|
|
237
|
+
except Exception:
|
|
238
|
+
pass
|
|
239
|
+
self._beforeLast().setSelection(
|
|
240
|
+
attrs["index"], [offset, block, count, stride])
|
|
241
|
+
#: (:obj:`str`) index attribute
|
|
242
|
+
self.__index = None
|
|
243
|
+
#: (:class:`nxswriter.DataSources.DataSource`) data source
|
|
244
|
+
self.source = None
|
|
245
|
+
#: (:obj:`list` <:obj:`str`>) tag content
|
|
246
|
+
self.content = []
|
|
247
|
+
if "index" in attrs.keys():
|
|
248
|
+
self.__index = attrs["index"]
|
|
249
|
+
|
|
250
|
+
def store(self, xml=None, globalJSON=None):
|
|
251
|
+
""" stores the tag content
|
|
252
|
+
|
|
253
|
+
:param xml: xml setting
|
|
254
|
+
:type xml: :obj: `str`
|
|
255
|
+
:param globalJSON: global JSON string
|
|
256
|
+
:type globalJSON: \
|
|
257
|
+
: :obj:`dict` <:obj:`str`, :obj:`dict` <:obj:`str`, any>>
|
|
258
|
+
"""
|
|
259
|
+
if self.__index is not None and self.source:
|
|
260
|
+
dt = self.source.getData()
|
|
261
|
+
if dt and isinstance(dt, dict):
|
|
262
|
+
dh = DataHolder(streams=self._streams, **dt)
|
|
263
|
+
if dh:
|
|
264
|
+
slab = json.loads(str(dh.cast("string")))
|
|
265
|
+
if isinstance(slab, list):
|
|
266
|
+
self._beforeLast().setSelection(self.__index, slab[:4])
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class ESlice(Element):
|
|
270
|
+
|
|
271
|
+
""" slice tag element
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
def __init__(self, attrs, last, streams=None):
|
|
275
|
+
""" constructor
|
|
276
|
+
|
|
277
|
+
:param attrs: dictionary of the tag attributes
|
|
278
|
+
:type attrs: :obj:`dict` <:obj:`str`, :obj:`str`>
|
|
279
|
+
:param last: the last element from the stack
|
|
280
|
+
:type last: :class:`nxswriter.Element.Element`
|
|
281
|
+
:param streams: tango-like steamset class
|
|
282
|
+
:type streams: :class:`StreamSet` or :class:`tango.LatestDeviceImpl`
|
|
283
|
+
"""
|
|
284
|
+
Element.__init__(self, "slice", attrs, last, streams=streams)
|
|
285
|
+
if ("index" in attrs.keys()):
|
|
286
|
+
added = False
|
|
287
|
+
start = None
|
|
288
|
+
stop = None
|
|
289
|
+
step = None
|
|
290
|
+
if "start" in attrs.keys() and attrs["start"]:
|
|
291
|
+
try:
|
|
292
|
+
start = int(attrs["start"])
|
|
293
|
+
added = True
|
|
294
|
+
except Exception:
|
|
295
|
+
pass
|
|
296
|
+
if "stop" in attrs.keys() and attrs["stop"]:
|
|
297
|
+
try:
|
|
298
|
+
stop = int(attrs["stop"])
|
|
299
|
+
added = True
|
|
300
|
+
except Exception:
|
|
301
|
+
pass
|
|
302
|
+
if "step" in attrs.keys() and attrs["step"]:
|
|
303
|
+
try:
|
|
304
|
+
step = int(attrs["step"])
|
|
305
|
+
added = True
|
|
306
|
+
except Exception:
|
|
307
|
+
pass
|
|
308
|
+
if added:
|
|
309
|
+
self._beforeLast().setSelection(
|
|
310
|
+
attrs["index"], slice(start, stop, step))
|
|
149
311
|
#: (:obj:`str`) index attribute
|
|
150
312
|
self.__index = None
|
|
151
313
|
#: (:class:`nxswriter.DataSources.DataSource`) data source
|
|
@@ -169,8 +331,10 @@ class EDim(Element):
|
|
|
169
331
|
if dt and isinstance(dt, dict):
|
|
170
332
|
dh = DataHolder(streams=self._streams, **dt)
|
|
171
333
|
if dh:
|
|
172
|
-
|
|
173
|
-
|
|
334
|
+
lslice = json.loads(str(dh.cast("string")))
|
|
335
|
+
if isinstance(lslice, list):
|
|
336
|
+
self._beforeLast().setSelection(
|
|
337
|
+
self.__index, slice(*lslice))
|
|
174
338
|
|
|
175
339
|
|
|
176
340
|
class EFilter(Element):
|
nxswriter/NexusXMLHandler.py
CHANGED
|
@@ -28,11 +28,13 @@ from .Element import Element
|
|
|
28
28
|
from .FElement import FElement
|
|
29
29
|
from .EGroup import EGroup
|
|
30
30
|
from .EField import EField
|
|
31
|
+
from .EVirtualField import EVirtualField, EVirtualDataMap, EVirtualSourceView
|
|
31
32
|
from .EAttribute import EAttribute
|
|
32
33
|
from .EStrategy import EStrategy
|
|
33
34
|
from .ELink import ELink
|
|
34
35
|
from .H5Elements import (
|
|
35
|
-
EDoc, ESymbol, EDimensions, EDim, EFile, EFilter
|
|
36
|
+
EDoc, ESymbol, EDimensions, EDim, EFile, EFilter, ESlab, ESlice,
|
|
37
|
+
ESelection)
|
|
36
38
|
from .DataSourceFactory import DataSourceFactory
|
|
37
39
|
from .ThreadPool import ThreadPool
|
|
38
40
|
from .InnerXMLParser import InnerXMLHandler
|
|
@@ -121,7 +123,10 @@ class NexusXMLHandler(sax.ContentHandler):
|
|
|
121
123
|
'symbols': Element, 'symbol': ESymbol,
|
|
122
124
|
'dimensions': EDimensions, 'dim': EDim,
|
|
123
125
|
'enumeration': Element, 'item': Element,
|
|
124
|
-
'strategy': EStrategy, 'filter': EFilter
|
|
126
|
+
'strategy': EStrategy, 'filter': EFilter,
|
|
127
|
+
'vds': EVirtualField, 'map': EVirtualDataMap,
|
|
128
|
+
'sourceview': EVirtualSourceView,
|
|
129
|
+
'slab': ESlab, 'slice': ESlice, 'selection': ESelection,
|
|
125
130
|
}
|
|
126
131
|
|
|
127
132
|
#: (:obj:`list` <:obj:`dict` <:obj:`str`, :obj:`str` > >) \
|
|
@@ -130,7 +135,7 @@ class NexusXMLHandler(sax.ContentHandler):
|
|
|
130
135
|
|
|
131
136
|
#: (:obj:`dict` <:obj:`str`, :obj:`type` > ) \
|
|
132
137
|
#: map of tag names to related classes
|
|
133
|
-
self.withAttr = ['group', 'field']
|
|
138
|
+
self.withAttr = ['group', 'field', 'vds']
|
|
134
139
|
|
|
135
140
|
#: (:obj:`list` <:obj:`str`>) transparent tags
|
|
136
141
|
self.transparentTags = ['definition']
|
nxswriter/Release.py
CHANGED
nxswriter/TangoDataWriter.py
CHANGED
|
@@ -71,6 +71,7 @@ DEFAULTWRITERS = ["h5cpp", "h5py", "h5redis"]
|
|
|
71
71
|
#: (:obj:`bool`) tango bug #213 flag related to EncodedAttributes in python3
|
|
72
72
|
PYTG_BUG_213 = False
|
|
73
73
|
if sys.version_info > (3,):
|
|
74
|
+
unicode = str
|
|
74
75
|
try:
|
|
75
76
|
try:
|
|
76
77
|
import tango
|
|
@@ -315,9 +316,12 @@ class TangoDataWriter(object):
|
|
|
315
316
|
"""
|
|
316
317
|
self.__fetcher = FetchNameHandler(streams=self._streams)
|
|
317
318
|
if sys.version_info > (3,):
|
|
318
|
-
sax.parseString(bytes(xmlset, 'utf-8'), self.__fetcher)
|
|
319
|
-
else:
|
|
320
319
|
sax.parseString(xmlset, self.__fetcher)
|
|
320
|
+
else:
|
|
321
|
+
if isinstance(xmlset, unicode):
|
|
322
|
+
sax.parseString(xmlset.encode('utf-8'), self.__fetcher)
|
|
323
|
+
else:
|
|
324
|
+
sax.parseString(xmlset, self.__fetcher)
|
|
321
325
|
self.__xmlsettings = xmlset
|
|
322
326
|
|
|
323
327
|
def __delXML(self):
|
|
@@ -504,7 +508,15 @@ class TangoDataWriter(object):
|
|
|
504
508
|
parser.setContentHandler(handler)
|
|
505
509
|
parser.setErrorHandler(errorHandler)
|
|
506
510
|
inpsrc = sax.InputSource()
|
|
507
|
-
|
|
511
|
+
if sys.version_info > (3,):
|
|
512
|
+
inpsrc.setByteStream(StringIO(self.xmlsettings))
|
|
513
|
+
else:
|
|
514
|
+
if isinstance(self.xmlsettings, unicode):
|
|
515
|
+
inpsrc.setByteStream(
|
|
516
|
+
StringIO(self.xmlsettings.encode('utf-8')))
|
|
517
|
+
else:
|
|
518
|
+
inpsrc.setByteStream(StringIO(self.xmlsettings))
|
|
519
|
+
|
|
508
520
|
parser.parse(inpsrc)
|
|
509
521
|
|
|
510
522
|
self.__initPool = handler.initPool
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: nxswriter
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.14.0
|
|
4
4
|
Summary: Nexus Data writer implemented as a Tango Server
|
|
5
5
|
Home-page: https://github.com/nexdatas/nxsdatawriter
|
|
6
6
|
Author: Jan Kotanski, Eugen Wintersberger , Halil Pasic
|
|
@@ -89,12 +89,12 @@ Extract sources and run
|
|
|
89
89
|
|
|
90
90
|
.. code-block:: console
|
|
91
91
|
|
|
92
|
-
$
|
|
92
|
+
$ python3 setup.py install
|
|
93
93
|
|
|
94
94
|
Debian packages
|
|
95
95
|
"""""""""""""""
|
|
96
96
|
|
|
97
|
-
Debian `bookworm`, `bullseye`, `buster` or Ubuntu `
|
|
97
|
+
Debian `bookworm`, `bullseye`, `buster` or Ubuntu `oracular`, `noble`, `jammy` packages can be found in the HDRI repository.
|
|
98
98
|
|
|
99
99
|
To install the debian packages, add the PGP repository key
|
|
100
100
|
|
|
@@ -175,7 +175,7 @@ To set up NeXus Writer Server run
|
|
|
175
175
|
|
|
176
176
|
$ nxsetup -x NXSDataWriter
|
|
177
177
|
|
|
178
|
-
The *nxsetup* command comes from the **
|
|
178
|
+
The *nxsetup* command comes from the **python3-nxstools** package.
|
|
179
179
|
|
|
180
180
|
-----------
|
|
181
181
|
Client code
|
|
@@ -5,33 +5,34 @@ nxswriter/DataSourceFactory.py,sha256=W0IirDjsu38KKvBxFbkvv-ghvqil2JJStQ3WMxo8Kh
|
|
|
5
5
|
nxswriter/DataSourcePool.py,sha256=1bDOrHhYpG_ZFz8ut2IzkNSMeGxrCBcSCneM4h1AgDc,4574
|
|
6
6
|
nxswriter/DataSources.py,sha256=l40n4WTfgRjLpFsJs7JoWjsER_dCVviRI_iolQ2fENM,5303
|
|
7
7
|
nxswriter/DecoderPool.py,sha256=8nsKtzwyls-YLZUJAfxdGrqb2278Er1Y20NVq1XexvY,15052
|
|
8
|
-
nxswriter/EAttribute.py,sha256=
|
|
9
|
-
nxswriter/EField.py,sha256=
|
|
8
|
+
nxswriter/EAttribute.py,sha256=hADI-LeuQMZwVoTFM4qevoz173Ma_atrk0edqvsFXS0,8878
|
|
9
|
+
nxswriter/EField.py,sha256=YLbdaykGccZ4cjqheS9te50FG6HQq5kfp7gg_OBkJ9k,28034
|
|
10
10
|
nxswriter/EGroup.py,sha256=Y_PuTERckQXfUXGISbnpzHj7I4y2iFxM5CGByjVD6KA,4900
|
|
11
11
|
nxswriter/ELink.py,sha256=FO7SRF1bpJhqRzK2FBSkRHhFwH1Mw5BRCgt8X8qJbr0,8820
|
|
12
12
|
nxswriter/EStrategy.py,sha256=3RX8E6Ee-Klv9DGlMPvXJacdNDmuKWLQrcnuerR0IQI,3992
|
|
13
|
+
nxswriter/EVirtualField.py,sha256=ZECzyGb4wZoBohHlwkcilpOtDHuA907VoruLDe9RN9k,24971
|
|
13
14
|
nxswriter/Element.py,sha256=dnIUS_U0fqJK3FxV_raQBx6qTGPT7sUFkWVzxI5YuEY,3019
|
|
14
15
|
nxswriter/ElementThread.py,sha256=gCZRpzjji8TRfWLkwFRXG_K55d0yUkv9Gzi2DZ22EyQ,2099
|
|
15
16
|
nxswriter/Errors.py,sha256=dYXtJ7rVWv59kAalNMMZO4X3SxSplhoWICeCb3_rFGc,1660
|
|
16
|
-
nxswriter/FElement.py,sha256=
|
|
17
|
+
nxswriter/FElement.py,sha256=ebQT2HHPmR6_J8H8ILa7G-gMDDNrEIUNh7sIfm9SF1I,20622
|
|
17
18
|
nxswriter/FetchNameHandler.py,sha256=WbIJcxB9wjUHAIgXpZOzxBBAlWMhg-zYiLw_2sxcBIY,6829
|
|
18
|
-
nxswriter/H5Elements.py,sha256=
|
|
19
|
+
nxswriter/H5Elements.py,sha256=64BFlgfaPEuRzWyWjkdfMhwF6oMc_NzAqAoKaZGAigo,13263
|
|
19
20
|
nxswriter/InnerXMLParser.py,sha256=Cr5Ih-51LGi8sKQi1qUUikL2K5hjwwilJo-j1kWHgds,4493
|
|
20
21
|
nxswriter/Metadata.py,sha256=Qg5KdlreERGG5CTZrCRAJXwBXxg96toyZ8wkknmdB3s,3668
|
|
21
22
|
nxswriter/NXSFromXML.py,sha256=932BivWZnf-3tnIkbpSRFwfGV0PTwcT9pYb2FMmVd_4,9077
|
|
22
23
|
nxswriter/NXSWriter.py,sha256=raHykC9mpUXU8pPtsqePuz3CI-24qYjIUSoyux2zCgo,31345
|
|
23
|
-
nxswriter/NexusXMLHandler.py,sha256=
|
|
24
|
+
nxswriter/NexusXMLHandler.py,sha256=IrZ2mWLuovdBIHcWTqKmr4HZxpMEWLun8A94O6pavr8,14131
|
|
24
25
|
nxswriter/PyEvalSource.py,sha256=7-7Gc2_3CGd3XMHD3LBPCBOZx4Q6b1guzt1xgrSLxMs,11234
|
|
25
|
-
nxswriter/Release.py,sha256=
|
|
26
|
+
nxswriter/Release.py,sha256=qNmln5Ifl--7uY5SpcQDkGFLFbqPVDYTmjV_3yQqLQI,900
|
|
26
27
|
nxswriter/StreamSet.py,sha256=sSvXJxoDufmt9_Xu5rFaQsp_4x9gww_zMv0NTiiyLlg,5799
|
|
27
|
-
nxswriter/TangoDataWriter.py,sha256=
|
|
28
|
+
nxswriter/TangoDataWriter.py,sha256=yP6B3TVUhpHp8OBHKYQRNNtFer9xARoakNXuro4eVv8,28725
|
|
28
29
|
nxswriter/TangoSource.py,sha256=jiFGUsoX2N5-i2gpBqkHi2KjmTBd46TI22Cjkt_2btw,29410
|
|
29
30
|
nxswriter/ThreadPool.py,sha256=TKvOStVUUyuyHowk0MRaBM4GmRKtl0VPVVPdFHu332M,6039
|
|
30
31
|
nxswriter/Types.py,sha256=CY_qw5-pbbDutRErgA6hbUTh903QA_IXc-CGSfuBje8,7676
|
|
31
32
|
nxswriter/__init__.py,sha256=M0w3HGjZgfdqjMdQNaLcq5jazqQeRekx84YSbQCA8-0,1760
|
|
32
|
-
nxswriter-3.
|
|
33
|
-
nxswriter-3.
|
|
34
|
-
nxswriter-3.
|
|
35
|
-
nxswriter-3.
|
|
36
|
-
nxswriter-3.
|
|
37
|
-
nxswriter-3.
|
|
33
|
+
nxswriter-3.14.0.data/scripts/NXSDataWriter,sha256=wO3opCCjYttfrY7CITNXHvirXv5W6rIQTY7vX5PmioI,905
|
|
34
|
+
nxswriter-3.14.0.data/scripts/nxsfromxml,sha256=qxnJUtV_ueA3lGnne8ltaOF6yF5YtmzeFLIl3NWkAq8,61
|
|
35
|
+
nxswriter-3.14.0.dist-info/METADATA,sha256=53Fc3OKmRlNatTbdcs0-lhBae1UoQkkPWLDvY_KAshY,8964
|
|
36
|
+
nxswriter-3.14.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
|
37
|
+
nxswriter-3.14.0.dist-info/top_level.txt,sha256=29dYcOYN2MVz1NKpwobc4Zl4yjhd4VB62LDSuSy7x0Y,10
|
|
38
|
+
nxswriter-3.14.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|