from collections import namedtuple
from ctypes import c_double
from ..tecutil import _tecutil, Index, IndexSet, lock
from .. import layout
from ..constant import *
from ..exception import *
# noinspection PyIncorrectDocstring
@lock()
[docs]def probe_at_position(x, y, z=None, nearest=False, starting_cell=None,
starting_zone=None, zones=None, dataset=None, frame=None):
"""Returns field values at a point in space.
.. note::
The position is taken according the axis assignments of the `Frame`
which may be any of the associated variables in the `Dataset` and not
necessarily ``(X, Y, Z)``. See: `Cartesian3DFieldAxis.variable`.
Parameters:
x,y,z (`float`, *z* is optional): position to probe for field values.
nearest (`bool`): Returns the values at the nearest node to the given
position.
starting_cell (3-`tuple` of `integers <int>`, optional):
The ``(i,j,k)``-index of the cell to start looking for the given
position. This must be used with ``starting_zone``.
starting_zone (`Zone`, required only when ``starting_cell`` is given):
The first zone to start searching.
zones (`list` of `Zones <Zone>`, optional): Limits the search to
the given zones. `None` implies searching all zones. (default:
`None`)
dataset (`Dataset`, optional): The `Dataset` to probe. (defaults to
the active `Dataset`.)
frame (`Frame`, optional): The `Frame` which determines the spatial
variable assignment ``(X,Y,Z)``. (defaults to the active `Frame`.)
Returns:
`namedtuple <collections.namedtuple>`: ``(data, cell, zone)``:
``data`` (`list` of `floats <float>`)
The values of each variable in the dataset at the given
position.
``cell`` (3-`tuple` of `integers <int>`)
``(i,j,k)`` of the cell containing the given position.
``zone`` (`Zone`)
Zone containing the given position
"""
if __debug__:
if frame and dataset and frame.dataset != dataset:
msg = ('Dataset must be attached to the input Frame: {} != {}'.
format(repr(frame.dataset), repr(dataset)))
raise TecplotValueError(msg)
if (starting_cell is None) ^ (starting_zone is None):
msg = 'starting_cell option requires an associated starting_zone'
raise TecplotLogicError(msg)
if dataset is None:
if frame is None:
frame = layout.active_frame()
dataset = frame.dataset
elif frame is None:
frame = dataset.frame
with frame.activated():
if starting_cell is None:
start_with_local_cell = False
i, j, k = 0, 0, 0
starting_zone_index = 0
else:
start_with_local_cell = True
i, j, k = (x+1 for x in starting_cell)
starting_zone_index = starting_zone.index
allocd = []
if zones is not None:
zones = IndexSet(*zones)
allocd.append(zones)
data = (max(3, dataset.num_variables)*c_double)()
result = _tecutil.ProbeAtPosition(x, y, z or 0, i, j, k,
IJKPlanes.Volume.value, starting_zone_index+1, start_with_local_cell,
data, zones, z is not None, False, nearest)
success, i, j, k, plane, zone_index = result
if not success:
raise TecplotSystemError()
cell = (Index(i-1), Index(j-1), Index(k-1))
zone_index = Index(zone_index-1)
for a in allocd:
a.dealloc()
probe_return_tuple = namedtuple('probe_return_tuple', ['data', 'cell', 'zone'])
return probe_return_tuple(data[:], cell, dataset.zone(zone_index))