добавить массив как новое векторное / скалярное поле из кадра данных Pandas с программируемым фильтром и консолью Python Paraview - PullRequest
0 голосов
/ 27 августа 2018

У меня есть фрейм данных следующего формата

ID  t_0       t_1     t_2     t_n
0    .         .       .       .    
.
.
m

и я хочу прочитать и добавить каждый массив столбцов в виде поля на соответствующем временном шаге к существующему набору файлов vtu (vtkXMLUnstructuredGrid), чтобы я мог создавать дополнительные фильтры в paraview и создавать конвейер.

Part1 - Using the Programmable Filter

frame = pd.read_hdf('/path/to/file/frame.h5', 'table', mode='r')

ts = self.GetInputDataObject(0,0).GetInformation().Get(vtk.vtkDataObject.DATA_TIME_STEP())

t = int(ts)

wantedArray = frame.filter(['t_{}'.format(t)], axis=1)

from numpy import array

a = array(wantedArray)

output.PointData.append(a, "newField")

Данный скрипт работает. Тем не менее, поскольку размер данных достаточно велик (~ 10 ГБ), при переходе к следующему временному шагу весь процесс замедляется, поскольку при обновлении конвейера кадр данных снова читается. Можно ли один раз прочитать большой файл .h5, сохранить его в памяти и получить доступ к данным?

Part 2 - Using paraview's python console

>>> frame = pd.read_hdf('/path/to/file/frame.h5', 'table', mode='r')
>>> view = GetActiveView()
>>> t = int(view.ViewTime)
>>> inputSource = GetActiveSource()
>>> inputData = servermanager.Fetch(inputSource)
>>> nPoints=inputData.GetNumberOfPoints()
>>> newField=paraview.vtk.vtkFloatArray()
>>> newwField.SetNumberOfValues(nPoints)
>>> newField.SetName("newField")

>>> wantedArray = frame.filter(['t_{}'.format(t)], axis=1)

>>> from numpy import array
>>> a = array(wantedArray)

>>> for k in range(nPoints):
    ...newField.SetValue(k, a[k])

>>> inputData.GetPointData().AddArray(newField)

Приведенный выше код создает правильное поле, и я могу получить доступ к значениям в консоли python с помощью

inputData.GetPointData().GetArray("newField").GetValue()

Проблема в том, что я не могу визуализировать этот массив в представлении рендеринга и обрабатывать его дальше с помощью других фильтров. Как мне вернуть этот массив, чтобы он отображался в представлении рендеринга (графическом интерфейсе) как поле в раскрывающемся списке?

Я пробовал несколько вещей, таких как Show(), Render(), но не сработало. Я также попробовал следующий фрагмент кода:

t = TrivialProducer() 
filter = t.GetClientSideObject()
filter.SetOutput(inputData)
t.UpdatePipeline()  

но это выдает следующую ошибку:

AttributeError: 'NoneType' object has no attribute 'SetOutput'

Любые альтернативные предложения также приветствуются. Я хочу реализовать это максимально эффективно!

...