Commit dd95e08b authored by Simeon Doetsch's avatar Simeon Doetsch

Added support for VTK legacy file format (only single file)

parent d69dace7
import numpy as np
from collections import OrderedDict
from itertools import zip_longest
from os.path import join
from .coordinates import generate_coordinate_mesh
......@@ -78,8 +79,12 @@ class Grid:
class SimulationMetadata:
def __init__(self, path, format) -> None:
self.read_vars(path, format)
def __init__(self, data_dir, format) -> None:
self.read_vars(join(data_dir, '{}.out'.format(format)), format)
# read VTK offsets in file
if format == 'vtk' and self.file_mode == 'single':
self.vtk_offsets = vtk_offsets(join(data_dir, 'data.0000.vtk'))
def read_vars(self, path, format) -> None:
"""Read simulation step data and written variables"""
......@@ -103,8 +108,37 @@ class SimulationMetadata:
self.charsize = 8 if format == 'dbl' else 4
endianness = '<' if endianness == 'little' else '>'
if format == 'vtk': endianness = '>' # VTK has always big endian
self.binformat = "{}f{}".format(endianness, self.charsize)
def vtk_offsets(filename) -> dict:
"""
Read positions of vars in VTK legacy file
"""
offsets = {}
with open(filename, 'rb') as f:
for l in f:
if not l or l == b'\n':
continue
split = l.split()
# skip coordinates (read in via gridfile)
if split[0] in [i + b'_COORDINATES' for i in [b"X", b"Y", b"Z",]]:
f.seek(int(split[1]) * 4 + 1, 1)
if split[0] == b'CELL_DATA':
bytesize = int(split[1]) * 4
# save position of variables
if split[0] == b'SCALARS':
var = split[1].decode()
f.readline() # skip "LOOKUP_TABLE"
offsets[var] = f.tell()
f.seek(bytesize, 1)
return offsets
class Pluto_ini(OrderedDict):
"""Parser for Plutocode initialization file pluto.ini"""
......
......@@ -57,13 +57,17 @@ class PlutoData(object):
def _load_var(self, var):
"""Load data for var into memory. Read either var dbl file (multiple_files mode),
or, slice data from single dbl file"""
if self.file_mode == 'single':
filename = "data.{n:04d}.{format}".format(n=self.n, format=self.format)
# byte offset of variable in dbl file
offset = self.charsize * self.size * self.vars.index(var)
elif self.file_mode == 'multiple':
filename = "{var}.{:04d}.{format}".format(var=var, n=self.n, format=self.format)
offset = 0
if self.format in ('dbl', 'flt'):
if self.file_mode == 'single':
filename = "data.{n:04d}.{format}".format(n=self.n, format=self.format)
# byte offset of variable in dbl file
offset = self.charsize * self.size * self.vars.index(var)
elif self.file_mode == 'multiple':
filename = "{var}.{:04d}.{format}".format(var=var, n=self.n, format=self.format)
offset = 0
elif self.format == 'vtk':
filename = "data.{n:04d}.vtk".format(n=self.n)
offset = self.simulation.metadata.vtk_offsets[var]
shape = tuple(reversed(self.data_shape))
......
......@@ -19,7 +19,7 @@ class Simulation:
loads individual files when needed.
Simulation is subscriptable and iterable.
"""
supported_formats = ('dbl', 'flt')
supported_formats = ('dbl', 'flt', 'vtk')
DataObject = PlutoData
def __init__(self, sim_dir: str='', format: str=None, coordinates: str=None) -> None:
......@@ -67,7 +67,7 @@ class Simulation:
"for format {} not found".format(join(self.data_dir, format+'.out'), format))
## Read metadata ##
self.metadata = SimulationMetadata(join(self.data_dir, '{}.out'.format(self.format)), self.format)
self.metadata = SimulationMetadata(join(self.data_dir), self.format)
self.vars = self.metadata.vars
## Read grid coordinate system ##
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment