pytecplot 1.5.2__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.
Files changed (97) hide show
  1. pytecplot-1.5.2.dist-info/LICENSE.html +77 -0
  2. pytecplot-1.5.2.dist-info/METADATA +508 -0
  3. pytecplot-1.5.2.dist-info/RECORD +97 -0
  4. pytecplot-1.5.2.dist-info/WHEEL +5 -0
  5. pytecplot-1.5.2.dist-info/top_level.txt +1 -0
  6. tecplot/__init__.py +94 -0
  7. tecplot/annotation/__init__.py +7 -0
  8. tecplot/annotation/annotation.py +223 -0
  9. tecplot/annotation/geometry.py +369 -0
  10. tecplot/annotation/georeference.py +33 -0
  11. tecplot/annotation/image.py +185 -0
  12. tecplot/annotation/iter.py +105 -0
  13. tecplot/annotation/polyline.py +381 -0
  14. tecplot/annotation/text.py +744 -0
  15. tecplot/constant.py +401 -0
  16. tecplot/data/__init__.py +34 -0
  17. tecplot/data/array.py +645 -0
  18. tecplot/data/create.py +1 -0
  19. tecplot/data/dataset.py +1809 -0
  20. tecplot/data/extract.py +544 -0
  21. tecplot/data/face_neighbors.py +494 -0
  22. tecplot/data/facemap.py +814 -0
  23. tecplot/data/load.py +2075 -0
  24. tecplot/data/nodemap.py +577 -0
  25. tecplot/data/operate.py +928 -0
  26. tecplot/data/query.py +334 -0
  27. tecplot/data/save.py +343 -0
  28. tecplot/data/variable.py +280 -0
  29. tecplot/data/zone.py +841 -0
  30. tecplot/exception.py +201 -0
  31. tecplot/export/__init__.py +13 -0
  32. tecplot/export/animation.py +521 -0
  33. tecplot/export/export_setup.py +318 -0
  34. tecplot/export/image.py +577 -0
  35. tecplot/export/print_setup.py +218 -0
  36. tecplot/export/time_animation.py +607 -0
  37. tecplot/extension/__init__.py +14 -0
  38. tecplot/extension/ipython.py +68 -0
  39. tecplot/layout/__init__.py +20 -0
  40. tecplot/layout/frame.py +1285 -0
  41. tecplot/layout/layout.py +488 -0
  42. tecplot/layout/page.py +541 -0
  43. tecplot/legend/__init__.py +4 -0
  44. tecplot/legend/contour_legend.py +516 -0
  45. tecplot/legend/legend.py +141 -0
  46. tecplot/legend/line_legend.py +66 -0
  47. tecplot/legend/rgb_coloring_legend.py +291 -0
  48. tecplot/legend/scatter_legend.py +136 -0
  49. tecplot/macro.py +339 -0
  50. tecplot/plot/__init__.py +62 -0
  51. tecplot/plot/axes.py +881 -0
  52. tecplot/plot/axis.py +1350 -0
  53. tecplot/plot/blanking.py +584 -0
  54. tecplot/plot/contour.py +1302 -0
  55. tecplot/plot/effects.py +162 -0
  56. tecplot/plot/fieldmap.py +2159 -0
  57. tecplot/plot/grid.py +758 -0
  58. tecplot/plot/isosurface.py +1167 -0
  59. tecplot/plot/labels.py +338 -0
  60. tecplot/plot/linemap.py +1905 -0
  61. tecplot/plot/linking.py +489 -0
  62. tecplot/plot/plot.py +1791 -0
  63. tecplot/plot/rgb_coloring.py +281 -0
  64. tecplot/plot/scatter.py +396 -0
  65. tecplot/plot/slice.py +1544 -0
  66. tecplot/plot/streamtrace.py +1949 -0
  67. tecplot/plot/symbol.py +567 -0
  68. tecplot/plot/ticks.py +666 -0
  69. tecplot/plot/title.py +380 -0
  70. tecplot/plot/vector.py +679 -0
  71. tecplot/plot/view.py +868 -0
  72. tecplot/session/__init__.py +112 -0
  73. tecplot/session/aux_data.py +276 -0
  74. tecplot/session/config.py +92 -0
  75. tecplot/session/session.py +425 -0
  76. tecplot/session/state_changed.py +225 -0
  77. tecplot/session/style.py +504 -0
  78. tecplot/tecutil/__init__.py +16 -0
  79. tecplot/tecutil/arglist.py +230 -0
  80. tecplot/tecutil/captured_output.py +177 -0
  81. tecplot/tecutil/constant.py +1312 -0
  82. tecplot/tecutil/index_set.py +118 -0
  83. tecplot/tecutil/lock.py +36 -0
  84. tecplot/tecutil/message_pb2.py +39 -0
  85. tecplot/tecutil/preamble.py +54 -0
  86. tecplot/tecutil/stringlist.py +114 -0
  87. tecplot/tecutil/sv.py +1662 -0
  88. tecplot/tecutil/tecutil.py +12402 -0
  89. tecplot/tecutil/tecutil_client.py +627 -0
  90. tecplot/tecutil/tecutil_connector.py +937 -0
  91. tecplot/tecutil/tecutil_rpc.py +6845 -0
  92. tecplot/tecutil/util.py +332 -0
  93. tecplot/text/__init__.py +3 -0
  94. tecplot/text/font.py +224 -0
  95. tecplot/text/label_format.py +374 -0
  96. tecplot/text/textbox.py +106 -0
  97. tecplot/version.py +41 -0
tecplot/data/array.py ADDED
@@ -0,0 +1,645 @@
1
+ from builtins import range, super
2
+
3
+ import ctypes
4
+ import logging
5
+ import textwrap
6
+
7
+ from ctypes import (addressof, byref, cast, c_double, c_float, c_int8, c_int16,
8
+ c_int32, c_int64, c_void_p, POINTER)
9
+
10
+ from ..tecutil import _tecutil, _tecutil_connector
11
+ from ..constant import *
12
+ from ..exception import *
13
+ from .. import session, tecutil
14
+ from . import operate
15
+
16
+ log = logging.getLogger(__name__)
17
+
18
+
19
+ class Array(c_void_p):
20
+ """Low-level accessor for underlying data within a `Dataset <tecplot.data.Dataset>`.
21
+
22
+ This object exposes a list-like interface to the underlying data array.
23
+ Using it, values can be directly queried and modified. After any
24
+ modification to the data, the Tecplot Engine will have to be notified of
25
+ the change. This notification will happen automatically in most cases, but
26
+ can be turned off using the `suspend context <tecplot.session.suspend>` for
27
+ a significant performance increase on large data sets.
28
+
29
+ Accessing values within an `Array` is done through the standard ``[]``
30
+ syntax::
31
+
32
+ >>> print(array[3])
33
+ 3.1415
34
+
35
+ The numbers passed are interpreted just like Python's built-in
36
+ :py:class:`slice` object::
37
+
38
+ >>> # print the values at indices: 5, 7, 9
39
+ >>> print(array[5:10:2])
40
+ [1.0, 1.0, 1.0]
41
+
42
+ Elements within an array can be manipulated in-place with the assignment
43
+ operator::
44
+
45
+ >>> array[3] = 5.0
46
+ >>> print(array[3])
47
+ 5.0
48
+
49
+ Element-by-element access is *not* guaranteed to be performant and users
50
+ should avoid writing loops over indices in Python. Instead, whole arrays
51
+ should be used. This will effectively push the loop down to the underlying
52
+ native library and will be much faster in virtually all cases.
53
+
54
+ Consider this array of 10k elements::
55
+
56
+ >>> ds = frame.create_dataset('Dataset', ['x'])
57
+ >>> zn = ds.add_ordered_zone('Zone', 10000)
58
+ >>> array = zn.values('x')
59
+
60
+ The following loop, which takes the sine of all values in the array will
61
+ require several Python function calls per element which is a tremendous
62
+ overhead::
63
+
64
+ >>> import math
65
+ >>> for i in range(len(ar)):
66
+ ... ar[i] = math.sin(ar[i])
67
+
68
+ An immediate improvement on this can be made by looping over the elements
69
+ in Python only when reading the values, but assigning them using the
70
+ whole array. This will be several times faster for even modest arrays::
71
+
72
+ >>> ar[:] = [math.sin(x) for x in ar]
73
+
74
+ But there is still a large performance penalty for looping over elements
75
+ directly in Python and PyTecplot supports two solutions for large arrays:
76
+ `tecplot.data.operate.execute_equation` and `Array.as_numpy_array()`.
77
+ Please refer to these for details. Continuing with the example above, we
78
+ could accomplish the same thing with either of the following using
79
+ `execute_equation()` (assuming the array is identified by the first zone,
80
+ first variable)::
81
+
82
+ >>> from tecplot.data.operate import execute_equation
83
+ >>> execute_equation('V1 = SIN(V1)', zones=[dataset.zone(0)])
84
+
85
+ or by using the `numpy` library::
86
+
87
+ >>> import numpy as np
88
+ >>> ar[:] = np.sin(ar[:])
89
+
90
+ In both of these cases, the calculation of the sine and loop over elements
91
+ is pushed to the low level library and is much faster. Note that only the
92
+ `execute_equation()` solution does the calculation within Tecplot and does
93
+ not require the data to copied out to Python so it will typically be the
94
+ fastest option.
95
+
96
+ .. note::
97
+
98
+ When modifying data using this class, it may be necessary to update the
99
+ range of any associated contouring with a call to
100
+ `ContourLevels.reset()` or similar. This will ensure that the total
101
+ range of the new values is presented in the plot.
102
+ """
103
+ def __init__(self, zone, variable):
104
+ self.zone = zone
105
+ self.variable = variable
106
+ super().__init__(self._native_reference())
107
+
108
+ @property
109
+ def _cache(self):
110
+ if _tecutil_connector.suspended:
111
+ _tecutil_connector._delete_caches.append(self._delete_cache)
112
+ return True
113
+ else:
114
+ return False
115
+
116
+ def _delete_cache(self):
117
+ attrs = '''
118
+ _rnr _wnr _rrp _wrp
119
+ _location
120
+ _len
121
+ _data_type
122
+ '''.split()
123
+ for attr in attrs:
124
+ try:
125
+ delattr(self, attr)
126
+ except AttributeError:
127
+ pass
128
+
129
+ def _native_reference(self, writable=False):
130
+ args = (self.zone.dataset.uid, self.zone.index + 1, self.variable.index + 1)
131
+ if writable:
132
+ if self._cache:
133
+ if not hasattr(self, '_wnr'):
134
+ with tecutil.lock():
135
+ self._wnr = _tecutil.DataValueGetWritableNativeRefByUniqueID(*args)
136
+ return self._wnr
137
+ else:
138
+ with tecutil.lock():
139
+ return _tecutil.DataValueGetWritableNativeRefByUniqueID(*args)
140
+ else:
141
+ if self._cache:
142
+ if not hasattr(self, '_rnr'):
143
+ with tecutil.lock():
144
+ self._rnr = _tecutil.DataValueGetReadableNativeRefByUniqueID(*args)
145
+ return self._rnr
146
+ else:
147
+ with tecutil.lock():
148
+ return _tecutil.DataValueGetReadableNativeRefByUniqueID(*args)
149
+
150
+ @tecutil.lock()
151
+ def _raw_pointer(self, writable=False):
152
+ if _tecutil_connector.connected:
153
+ msg = 'raw pointer access only available in batch-mode'
154
+ raise TecplotLogicError(msg)
155
+ elif writable:
156
+ ref = self._native_reference(writable=True)
157
+ _tecutil.handle.tecUtilDataValueGetWritableRawPtrByRef.restype = \
158
+ POINTER(self.c_type)
159
+ wrp = _tecutil.DataValueGetWritableRawPtrByRef(ref)
160
+ if self._cache:
161
+ if not hasattr(self, '_wrp'):
162
+ self._wrp = wrp
163
+ return self._wrp
164
+ else:
165
+ return wrp
166
+ else:
167
+ _tecutil.handle.tecUtilDataValueGetReadableRawPtrByRef.restype = \
168
+ POINTER(self.c_type)
169
+ rrp = _tecutil.DataValueGetReadableRawPtrByRef(self)
170
+ if self._cache:
171
+ if not hasattr(self, '_rrp'):
172
+ self._rrp = rrp
173
+ return self._rrp
174
+ else:
175
+ return rrp
176
+
177
+ def __eq__(self, other):
178
+ self_addr = addressof(cast(self, POINTER(c_int64)).contents)
179
+ other_addr = addressof(cast(other, POINTER(c_int64)).contents)
180
+ return self_addr == other_addr
181
+
182
+ def __ne__(self, other):
183
+ return not (self == other)
184
+
185
+ def __len__(self):
186
+ """The number of values in this array.
187
+
188
+ :rtype: `integer <int>`
189
+
190
+ Example showing size of ordered data::
191
+
192
+ >>> x = dataset.zone('Zone').values('X')
193
+ >>> print(x.shape)
194
+ (10, 10, 10)
195
+ >>> print(len(x))
196
+ 1000
197
+ """
198
+ if self._cache:
199
+ if not hasattr(self, '_len'):
200
+ self._len = _tecutil.DataValueGetCountByRef(self)
201
+ return self._len
202
+ else:
203
+ return _tecutil.DataValueGetCountByRef(self)
204
+
205
+ @property
206
+ def location(self):
207
+ """`ValueLocation`: Data points location with respect to the elements.
208
+
209
+ Possible values are `ValueLocation.CellCentered` and
210
+ `ValueLocation.Nodal`. Example usage::
211
+
212
+ >>> print(dataset.zone(0).values('X').location)
213
+ ValueLocation.Nodal
214
+ """
215
+ if self._cache:
216
+ if not hasattr(self, '_location'):
217
+ self._location = _tecutil.DataValueGetLocation(
218
+ self.zone.index + 1, self.variable.index + 1)
219
+ return self._location
220
+ else:
221
+ return _tecutil.DataValueGetLocation(self.zone.index + 1,
222
+ self.variable.index + 1)
223
+
224
+ @property
225
+ def shape(self):
226
+ """`tuple` of `floats <float>`: ``(i, j, k)`` shape for this array.
227
+
228
+ This is defined by the parent zone and can be used to reshape arrays.
229
+ The following example assumes 32-bit floating point array and copies
230
+ the Tecplot-owned ``data`` into the `numpy`-owned ``array``::
231
+
232
+ >>> import numpy as np
233
+ >>> data = dataset.zone('Zone').values('X')
234
+ >>> array = np.empty(data.shape, dtype=np.float32)
235
+ >>> arr_ptr = array.ctypes.data_as(POINTER(data.c_type))
236
+ >>> memmove(arr_ptr, data.copy(), sizeof(data.c_type) * len(data))
237
+
238
+ The data array presented is normally one-dimensional. For ordered data,
239
+ you may wish to reshape the array indexing according to the
240
+ dimensionality given by the ``shape`` attribute:
241
+
242
+ .. code-block:: python
243
+ :emphasize-lines: 30
244
+
245
+ import numpy as np
246
+ import tecplot as tp
247
+
248
+ frame = tp.active_frame()
249
+ dataset = frame.create_dataset('Dataset', ['X'])
250
+ zone = dataset.add_ordered_zone('Zone', shape=(3,3,3))
251
+
252
+ '''
253
+ the following will print:
254
+ [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
255
+ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
256
+ '''
257
+ x = np.array(zone.values('X')[:])
258
+ print(x)
259
+
260
+ '''
261
+ the following will print:
262
+ [[[ 0. 0. 0.]
263
+ [ 0. 0. 0.]
264
+ [ 0. 0. 0.]]
265
+
266
+ [[ 0. 0. 0.]
267
+ [ 0. 0. 0.]
268
+ [ 0. 0. 0.]]
269
+
270
+ [[ 0. 0. 0.]
271
+ [ 0. 0. 0.]
272
+ [ 0. 0. 0.]]]
273
+ '''
274
+ x.shape = zone.values('X').shape
275
+ print(x)
276
+
277
+ """
278
+ if self.zone.zone_type is ZoneType.Ordered:
279
+ array_shape = tuple(i for i in self.zone._shape if i > 1)
280
+ else:
281
+ array_shape = (self.zone.num_points,)
282
+ if self.location is ValueLocation.CellCentered:
283
+ array_shape = tuple(i - 1 for i in array_shape if i > 2)
284
+ if not array_shape:
285
+ array_shape = (1,)
286
+ return array_shape
287
+
288
+ @property
289
+ def c_type(self):
290
+ """`ctypes` compatible data type of this array.
291
+
292
+ This is the `ctypes` equivalent of `Array.data_type` and will return
293
+ one of the following:
294
+
295
+ * `ctypes.c_float`
296
+ * `ctypes.c_double`
297
+ * `ctypes.c_int`
298
+ * `ctypes.c_int16`
299
+ * `ctypes.c_int8`
300
+
301
+ and can be used to create a `ctypes` array to store a copy of the
302
+ data:
303
+
304
+ .. code-block:: python
305
+
306
+ import tecplot as tp
307
+ frame = tp.active_frame()
308
+ dataset = frame.create_dataset('Dataset', ['x'])
309
+ dataset.add_ordered_zone('Zone', (3,3,3))
310
+ x = dataset.zone('Zone').values('x')
311
+ # allocate array using Python's ctypes
312
+ x_array = (x.c_type * len(x))()
313
+ # copy values from Dataset into ctypes array
314
+ x_array[:] = x[:]
315
+ """
316
+ _ctypes = {
317
+ FieldDataType.Float: ctypes.c_float,
318
+ FieldDataType.Double: ctypes.c_double,
319
+ FieldDataType.Int32: ctypes.c_int32,
320
+ FieldDataType.Int16: ctypes.c_int16,
321
+ FieldDataType.Byte: ctypes.c_int8}
322
+ return _ctypes[self.data_type]
323
+
324
+ @property
325
+ def data_type(self):
326
+ """`FieldDataType`: Indicating the underlying value type of this array.
327
+
328
+ Example usage::
329
+
330
+ >>> print(dataset.zone('Zone').values('X').data_type)
331
+ FieldDataType.Float
332
+ """
333
+ return _tecutil.DataValueGetRefType(self)
334
+
335
+ @tecutil.lock()
336
+ def as_ctypes_array(self, offset=0, size=None, copy=True):
337
+ """Present the underlying data array as a `ctypes.Array`.
338
+
339
+ If the **copy** parameter is `False`, this method will attempt to return
340
+ an array pointing to the actual data stored in the Tecplot Engine. This
341
+ will fail in connected mode or if the loader does not support
342
+ immediate loading of the entire array into memory. Care should be taken
343
+ to ensure the validity of the pointers to the data.
344
+
345
+ Parameters:
346
+ offset (`int`, optional): Zero-based offset into the array. This
347
+ will be the starting point of the resulting data. (default: 0)
348
+ size (`int`, optional): Number of elements in the resulting array.
349
+ The default (a value of `None`) is to go to the end of the
350
+ data.
351
+ copy (`bool`, optional): Copy the data out from the Tecplot Engine.
352
+ If `False`, an attempt is made to point to the underlying raw
353
+ data and an exception is thrown on error. (default: `True`)
354
+
355
+ Returns:
356
+ `ctypes.Array`
357
+
358
+ Example usage::
359
+
360
+ >>> x = dataset.zone('Zone').values('X').as_ctypes_array()
361
+ """
362
+ size = (len(self) - offset) if size is None else size
363
+ CArray = (self.c_type * size)
364
+ if copy:
365
+ arr = CArray()
366
+ _tecutil.DataValueArrayGetByRef(self, offset + 1, size, arr)
367
+ return arr
368
+ else:
369
+ ptr = self._raw_pointer(True)
370
+ if offset:
371
+ vptr = ctypes.cast(ctypes.pointer(ptr),
372
+ ctypes.POINTER(ctypes.c_void_p))
373
+ vptr.contents.value += ctypes.sizeof(ptr._type_) * offset
374
+ ptr_addr = ctypes.addressof(ptr.contents)
375
+ arr = CArray.from_address(ptr_addr)
376
+ return arr
377
+
378
+ def as_numpy_array(self, offset=0, size=None, copy=True):
379
+ """Present the underlying data array as a `numpy.ndarray`.
380
+
381
+ If the **copy** parameter is `False`, this method will attempt to return
382
+ an array pointing to the actual data stored in the Tecplot Engine. This
383
+ will fail in connected mode or if the loader does not support
384
+ immediate loading of the entire array into memory. Care should be taken
385
+ to ensure the validity of the pointers to the data.
386
+
387
+ Parameters:
388
+ offset (`int`, optional): Zero-based offset into the array. This
389
+ will be the starting point of the resulting data. (default: 0)
390
+ size (`int`, optional): Number of elements in the resulting array.
391
+ The default (a value of `None`) is to go to the end of the
392
+ data.
393
+ copy (`bool`, optional): Copy the data out from the Tecplot Engine.
394
+ If `False`, an attempt is made to point to the underlying raw
395
+ data and an exception is thrown on error. (default: `True`)
396
+
397
+ Returns:
398
+ `numpy.ndarray`
399
+
400
+ Example usage::
401
+
402
+ >>> x = dataset.zone('Zone').values('X').as_numpy_array()
403
+ """
404
+ import numpy as np
405
+ carr = self.as_ctypes_array(offset, size, copy)
406
+ return np.ctypeslib.as_array(carr)
407
+
408
+ @tecutil.lock()
409
+ def copy(self, offset=0, size=None):
410
+ """Copy the whole or part of the array into a ctypes array.
411
+
412
+ Parameters:
413
+ offset (`int`, optional): Zero-based offset for starting
414
+ index to copy. (default: 0)
415
+ size (`int`, optional): Number of values to copy into the
416
+ resulting array. A value of `None` will copy to the end of the
417
+ array. (default: `None`)
418
+
419
+ Here we will copy out chunks of the data, do some operation and set the
420
+ values back into the dataset:
421
+
422
+ .. code-block:: python
423
+
424
+ import tecplot as tp
425
+
426
+ tp.new_layout()
427
+ frame = tp.active_frame()
428
+ dataset = frame.create_dataset('Dataset', ['x'])
429
+ dataset.add_ordered_zone('Zone', (2, 2, 2))
430
+ x = dataset.zone('Zone').values('x')
431
+
432
+ # loop over array copying out 4 values at a time
433
+ for i, offset in enumerate(range(0, len(x), 4)):
434
+ x_array = x.copy(offset, 4)
435
+ x_array[:] = [i] * 4
436
+ x[offset:offset + 4] = x_array
437
+
438
+ # will print: [0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0]
439
+ print(x[:])
440
+ """
441
+ try:
442
+ return self.as_numpy_array(offset, size, copy=True)
443
+ except ImportError:
444
+ msg = textwrap.dedent('''\
445
+ Falling back to using basic Python for data operations.
446
+ If installed, PyTecplot will make use of Numpy where
447
+ appropriate for significant performance gains.
448
+ ''')
449
+ log.warning(msg)
450
+ return self.as_ctypes_array(offset, size, copy=True)
451
+
452
+ def _slice_range(self, s):
453
+ start = s.start or 0
454
+ if start < 0:
455
+ start += len(self)
456
+ stop = s.stop or len(self)
457
+ if stop < 0:
458
+ stop += len(self)
459
+ step = s.step or 1
460
+ return range(start, stop, step)
461
+
462
+ def __getitem__(self, i):
463
+ if not isinstance(i, slice):
464
+ return _tecutil.DataValueGetByRef(self, i + 1)
465
+ else:
466
+ s = self._slice_range(i)
467
+ if s.step > 1:
468
+ # i is a non-contiguous slice
469
+ return [_tecutil.DataValueGetByRef(self, ii + 1) for ii in s]
470
+ else:
471
+ # i is a contiguous slice
472
+ return self.copy(s.start, s.stop - s.start)
473
+
474
+ @tecutil.lock()
475
+ def __setitem__(self, i, val):
476
+ """
477
+ Developers note:
478
+ This method avoids using raw pointers which may not be available
479
+ for different reasons -- backing data does not support it, limited
480
+ memory resources or we are in connected mode for example.
481
+ """
482
+ if not isinstance(i, slice):
483
+ # i is an index
484
+ ref = self._native_reference(True)
485
+ _tecutil.DataValueSetByRef(ref, i + 1, val)
486
+ session.data_altered(self.zone, self.variable, i)
487
+ elif isinstance(val, Array) and val == self:
488
+ # self assignment no-op
489
+ return
490
+ else:
491
+ if callable(getattr(val, 'ravel', None)):
492
+ val = val.ravel()
493
+ s = self._slice_range(i)
494
+ if len(s) != len(val):
495
+ msg = 'Array length mismatch {} != {}'
496
+ raise TecplotIndexError(msg.format(len(s), len(val)))
497
+ if s.step > 1:
498
+ # i is a non-contiguous slice
499
+ # the following works, but is slow!
500
+ for a, b in enumerate(s):
501
+ self[b] = val[a]
502
+ else:
503
+ # i is a contiguous slice
504
+ offset = s.start
505
+ size = s.stop - s.start
506
+
507
+ if isinstance(val, Array):
508
+ if (
509
+ offset == 0 and
510
+ size in (None, len(self)) and
511
+ val.zone.dataset == self.zone.dataset
512
+ ):
513
+ # copy whole array
514
+ if val.zone == self.zone:
515
+ eqn = 'V{0} = V{1}'.format(self.variable.index + 1,
516
+ val.variable.index + 1)
517
+ operate.execute_equation(eqn, self.zone)
518
+ else:
519
+ src_zone_idx = self.zone.index
520
+ tgt_zone_idx = val.zone.index
521
+ var_idx = val.variable.index
522
+ if not _tecutil.DataValueCopy(src_zone_idx + 1,
523
+ tgt_zone_idx + 1,
524
+ var_idx + 1):
525
+ raise TecplotSystemError()
526
+ return
527
+ else:
528
+ # either sub array or different datasets
529
+ val = val.as_ctypes_array(copy=True)
530
+
531
+ ctype = self.c_type
532
+ if isinstance(val, ctypes.Array) and val._type_ == ctype:
533
+ arr = val
534
+ else:
535
+ # coerce val to a ctypes array, using numpy if available
536
+ try:
537
+ import numpy as np
538
+ nparr = np.asarray(val, dtype=ctype)
539
+ ptarr = nparr.ctypes.data_as(POINTER(ctype))
540
+ ptaddr = addressof(ptarr.contents)
541
+ arr = (ctype * size).from_address(ptaddr)
542
+ except ImportError:
543
+ msg = textwrap.dedent('''\
544
+ Falling back to using basic Python for data
545
+ operations. If installed, PyTecplot will make use
546
+ of Numpy where appropriate for significant
547
+ performance gains.
548
+ ''')
549
+ log.warning(msg)
550
+ arr = (ctype * size)(*val)
551
+
552
+ ref = self._native_reference(True)
553
+ _tecutil.DataValueArraySetByRef(ref, offset + 1, size, arr)
554
+ session.data_altered(self.zone, self.variable)
555
+
556
+ def __iter__(self):
557
+ self.current_index = -1
558
+ self.current_length = len(self)
559
+ return self
560
+
561
+ def __next__(self):
562
+ self.current_index += 1
563
+ if self.current_index < self.current_length:
564
+ return self.__getitem__(self.current_index)
565
+ else:
566
+ del self.current_index
567
+ del self.current_length
568
+ raise StopIteration
569
+
570
+ def next(self): # if sys.version_info < (3,)
571
+ return self.__next__()
572
+
573
+ def minmax(self):
574
+ """Limits of the values stored in this array.
575
+
576
+ :rtype: `tuple` of `floats <float>`
577
+
578
+ This always returns `floats <float>` regardless of the underlying data
579
+ type::
580
+
581
+ >>> print(dataset.zone('Zone').values('x').minmax())
582
+ (0, 10)
583
+ """
584
+ return _tecutil.DataValueGetMinMaxByRef(self)
585
+
586
+ def min(self):
587
+ """Lower bound of the values stored in this array.
588
+
589
+ :rtype: `float`
590
+
591
+ This always returns a `float` regardless of the underlying data type::
592
+
593
+ >>> print(dataset.zone('Zone').values('x').min())
594
+ 0
595
+ """
596
+ return self.minmax()[0]
597
+
598
+ def max(self):
599
+ """Upper bound of the values stored in this array.
600
+
601
+ :rtype: `float`
602
+
603
+ This always returns a `float` regardless of the underlying data type::
604
+
605
+ >>> print(dataset.zone('Zone').values('x').max())
606
+ 10
607
+ """
608
+ return self.minmax()[1]
609
+
610
+ @property
611
+ def shared_zones(self):
612
+ """`list` of `Zones <data_access>`: All `Zones <data_access>` sharing this array.
613
+
614
+ Example usage::
615
+
616
+ >>> dataset.zone('My Zone').copy(share_variables=True)
617
+ >>> for z in dataset.zone('My Zone').values(0).shared_zones:
618
+ ... print(z.index)
619
+ 0
620
+ 1
621
+ """
622
+ indices = _tecutil.DataValueGetShareZoneSet(self.zone.index + 1,
623
+ self.variable.index + 1)
624
+ ret = [self.zone.dataset.zone(i) for i in indices]
625
+ indices.dealloc()
626
+ return ret
627
+
628
+ @property
629
+ def passive(self):
630
+ """`bool`: An unallocated zone-variable combination.
631
+
632
+ Passive variables are placeholders where no data is defined for a zone
633
+ variable combination. Passive variables will always return zero when
634
+ queried:
635
+
636
+ .. code-block:: python
637
+
638
+ import tecplot as tp
639
+
640
+ ds = tp.active_page().add_frame().create_dataset('D', ['x','y'])
641
+ z = ds.add_ordered_zone('Z1', (3,))
642
+ assert not z.values(0).passive
643
+ """
644
+ return _tecutil.DataValueIsPassive(self.zone.index + 1,
645
+ self.variable.index + 1)
tecplot/data/create.py ADDED
@@ -0,0 +1 @@
1
+