Skip to content

Commit

Permalink
Merge pull request #296 from alhom/vtk_interface
Browse files Browse the repository at this point in the history
Experimental VTK interface for VLSV files, implemented via a rudimentary VTKPythonAlgorithmBase-based reader exposing a vtkHyperTreeGrid. This will cache HTG metadata on disk.

Includes a ParaView plugin script, wrapping the interface for ParaView access. Works on Paraview>=5.13.1.
  • Loading branch information
alhom authored Jan 17, 2025
2 parents 7416bf4 + 926e854 commit a520734
Show file tree
Hide file tree
Showing 6 changed files with 1,105 additions and 2 deletions.
18 changes: 18 additions & 0 deletions examples/write_htg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import vtk
import pytools as pt

# This initializes a hypertreegrid from the given reader.
reader = pt.vlsvfile.VlsvVtkReader()
reader.SetFileName("../../bulk.0002189.vlsv")

# These functions grab one SpatialGrid variable and map that to
# the hypertreegrid. Variable vector sizes of 1,2,3,4,9 supported.
reader.addArrayFromVlsv("vg_b_vol")
reader.addArrayFromVlsv("vg_beta_star")

reader.Update()

writer = vtk.vtkXMLHyperTreeGridWriter()
writer.SetFileName("output_EGE.htg")
writer.SetInputData(reader.GetOutputDataObject(0))
writer.Write()
70 changes: 70 additions & 0 deletions plugins/vlsvParaReader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
""" A rudimentary wrapper from the vlsvVtkInterface. Add and load from Paraview
plugins menu.
Built on Kitware example:
https://github.com/Kitware/ParaView/blob/master/Examples/Plugins/PythonAlgorithm/PythonAlgorithmExamples.py
This module demonstrates various ways of adding
VTKPythonAlgorithmBase subclasses as filters, sources, readers,
and writers in ParaView"""

# https://github.com/Kitware/ParaView/blob/master/Examples/Plugins/PythonAlgorithm/PythonAlgorithmExamples.py

# This is module to import. It provides VTKPythonAlgorithmBase, the base class
# for all python-based vtkAlgorithm subclasses in VTK and decorators used to
# 'register' the algorithm with ParaView along with information about UI.
from paraview.util.vtkAlgorithm import *
import pytools as pt

# Use the analysator reader, but include Paraview decorators via inheriting/chaining
# necessary methods etc

#------------------------------------------------------------------------------
# A reader example.
#------------------------------------------------------------------------------

# To add a reader, we can use the following decorators
# @smproxy.source(name="PythonCSVReader", label="Python-based CSV Reader")
# @smhint.xml("""<ReaderFactory extensions="csv" file_description="Numpy CSV files" />""")
# or directly use the "@reader" decorator.
@smproxy.reader(name="PythonVLSVReader", label="Python-based VLSV Reader, outputs htg",
extensions="vlsv", file_description="VLSV files")
class PythonPvVLSVReader(pt.vlsvfile.VlsvVtkReader):
"""A reader that wraps an Analysator VLSV file reader.
"""
def __init__(self):
super().__init__()


@smproperty.stringvector(name="FileName")
@smdomain.filelist()
@smhint.filechooser(extensions="vlsv", file_description="Vlasiator VLSV files")
def SetFileName(self, filename):
"""Specify filename for the file to read."""
if filename is None or filename == "None":
return
print(filename)
super().SetFileName(filename)

@smproperty.doublevector(name="TimestepValues", information_only="1", si_class="vtkSITimeStepsProperty")
def GetTimestepValues(self):
return None

# Array selection API is typical with readers in VTK
# This is intended to allow ability for users to choose which arrays to
# load. To expose that in ParaView, simply use the
# smproperty.dataarrayselection().
# This method **must** return a `vtkDataArraySelection` instance.
@smproperty.dataarrayselection(name="Arrays")
def GetDataArraySelection(self):
return super().GetDataArraySelection()


#------------------------------------------------------------------------------
# Todo: some tests
#------------------------------------------------------------------------------

def test_PythonVLSVReader(fname):
pass

if __name__ == "__main__":
pass
1 change: 1 addition & 0 deletions pyVlsv/vlsvfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
from vlsvreader import fsDecompositionFromGlobalIds,fsReadGlobalIdsPerRank,fsGlobalIdToGlobalIndex
from vlsvwriter import VlsvWriter
from vlasiatorreader import VlasiatorReader
from vlsvvtkinterface import VlsvVtkReader

from vlsvparticles import VlsvParticles
import reduction
Expand Down
39 changes: 37 additions & 2 deletions pyVlsv/vlsvreader.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,41 @@ def __check_datareducer(self, name, reducer):

return reducer_ok

def get_variables(self):

varlist = []

for child in self.__xml_root:
if child.tag == "VARIABLE" and "name" in child.attrib:
name = child.attrib["name"]
varlist.append(name)

return varlist

def get_reducers(self):

varlist = []

reducer_max_len = 0

for reducer_reg in [datareducers, multipopdatareducers, v5reducers, multipopv5reducers]:
for k in reducer_reg.keys():
reducer_max_len = max(reducer_max_len, len(k))



for reducer_reg in [datareducers, multipopdatareducers, v5reducers, multipopv5reducers]:
for name, reducer in reducer_reg.items():
self.__current_reducer_tree_nodes.clear()
if self.__check_datareducer(name,reducer):
if name[:3] == 'pop':
for pop in self.active_populations:
varlist.append(pop+'/'+name[4:])
else:
varlist.append(name)

return varlist


def list(self, parameter=True, variable=True, mesh=False, datareducer=False, operator=False, other=False):
''' Print out a description of the content of the file. Useful
Expand Down Expand Up @@ -1997,9 +2032,9 @@ def get_max_refinement_level(self):
if self.__max_spatial_amr_level < 0:
# Read the file index for cellid
cellids=self.read(mesh="SpatialGrid",name="CellID", tag="VARIABLE")
maxcellid = np.amax([cellids])
maxcellid = np.int64(np.amax([cellids]))

AMR_count = 0
AMR_count = np.int64(0)
while (maxcellid > 0):
maxcellid -= 2**(3*(AMR_count))*(self.__xcells*self.__ycells*self.__zcells)
AMR_count += 1
Expand Down
Loading

0 comments on commit a520734

Please sign in to comment.