Skip to content

Data

See VTK and XDMF data for fixed-mesh assumptions, VTK time metadata, interpolation, and cache behavior.

XDMF tools

Process timeseries data in XDMF.

https://www.xdmf.org/index.php/XDMF_Model_and_Format

AttributeType

Bases: StrEnum

Definition of variable type.

AttributeInfo dataclass

AttributeInfo(name, attribute_type, shape)

Information on attribute on the mesh (cell or point data).

XDMFInfo dataclass

XDMFInfo(path, tstart, tend, num_steps, num_points, num_cells, points, cells, point_data, cell_data)

Information about a given timecourse xdmf.

This includes information about the timepoints, scalars, vectors, ... . This is often required as base information before processing things.

  • figure out time points and range
  • figure out data limits
  • figure out scalars, vectors, ...

Preprocessing of all the important information for the visualization later on.

from_path staticmethod

from_path(xdmf_path)

Create XDMFInformation from xdmf path.

DataLimits dataclass

DataLimits(limits)

Limits of numerical data.

json_path_from_xdmf classmethod

json_path_from_xdmf(xdmf_path)

Calculate JSON path from xdmf path.

from_xdmf classmethod

from_xdmf(xdmf_path, overwrite=False)

Calculate data limits from XDMF timecourse..

This takes some time because it requires iteration over the complete dataset. Should support subsets and operations such as merging of limits from multiple simulations.

merge_limits staticmethod

merge_limits(data_limits)

Merge the limits from multiple data limits.

XDMFTimeSeriesWriter

XDMFTimeSeriesWriter(filename, data_format='HDF', *, share_identical_arrays=False, stack_time_steps=False)

Bases: TimeSeriesWriter

Write time series with compressed HDF data beside XDMF, in place.

This preserves meshio's TimeSeriesWriter context manager API and writes relative HDF references so that the XDMF and HDF files can be moved together.

Each HDF dataset is deflated with the byte-shuffle filter. This is a standard HDF5 filter; readers need nothing special and the stored values and dtypes are unchanged.

With share_identical_arrays, an array identical to one already written shares its storage through an HDF link instead of being stored twice. A fixed mesh repeats its time-invariant fields at every step, so sharing keeps a long history proportional to the data that actually changes. It is not the default because it makes the sidecar unsafe to edit in place: writing to one dataset then changes every array that shares its storage.

With stack_time_steps, each attribute becomes one growing dataset spanning the whole series, and every step references its slice through an XDMF HyperSlab. A dataset written one step at a time gives the compressor only a single frame to work with, while a chunk spanning consecutive steps exposes how little changes between them: on reconstructed scalar fields this measured 3.5x smaller than one dataset per step. The chunk spans as many steps as fit in :data:CHUNK_TARGET_BYTES, which keeps a single-step read to a few milliseconds.

meshio cannot read HyperSlab references, so a stacked series must be read with :class:XDMFTimeSeriesReader. ParaView reads them directly.

Record how arrays of the series are laid out in the HDF sidecar.

numpy_to_xml_string

numpy_to_xml_string(data)

Write one array compressed, optionally reusing an identical array.

point_data

point_data(point_data, grid)

Write node attributes, stacking them when the series is stacked.

cell_data

cell_data(cell_data, grid)

Write cell attributes, stacking them when the series is stacked.

XDMFTimeSeriesReader

Bases: TimeSeriesReader

Read a time series, resolving the HyperSlab references meshio cannot.

:class:XDMFTimeSeriesWriter can store each attribute as one dataset spanning the whole series, with every step referencing its slice through an XDMF HyperSlab. meshio has no HyperSlab support, so reading such a series needs this subclass. A series without HyperSlab references is read exactly as meshio reads it, which makes this a drop-in replacement.

Only the requested slice is read, so a step costs one chunk rather than the whole history.

xdmfs_from_directory

xdmfs_from_directory(input_dir, xdmf_dir, overwrite=False)

Create the XDMF files from a given input directory.

E.g. this is the FEBIO output directory. This should be a directory with possible subdirectories which contain VTK files. All subdirectories are processed.

Processes directory and all subdirectories which contain vtks. This allows to easily create all xdms for a given directory. XDMF file structure is analogue to the structure in the original directory

Parameters:

Name Type Description Default
input_dir Path

Directory containing VTK files, including subdirectories.

required
xdmf_dir Path

Directory in which the XDMF files are generated.

required
overwrite bool

Whether to replace existing output files.

False

Returns:

Type Description
dict[Path, Path]

A mapping from each XDMF output path to its VTK source directory.

vtks_to_xdmf

vtks_to_xdmf(vtk_dir, xdmf_path, overwrite=False)

Convert VTK timesteps to XDMF time course.

Parameters:

Name Type Description Default
vtk_dir Path

Directory containing VTK files ordered by timestep.

required
xdmf_path Path

Path to the XDMF output file.

required
overwrite bool

Whether to replace existing output files.

False

interpolate_xdmf

interpolate_xdmf(xdmf_in, xdmf_out, times_interpolate, overwrite=False)

Linearly interpolate point and cell data at finite times within the input range.

The input time series must have strictly increasing, finite timepoints. Requested times must form a nonempty one-dimensional array. Their order and repeated values are preserved. Output directories are created as needed.

Scalar datasets

These helpers select scalar fields and do not preserve mesh geometry.

Convert scalar XDMF time series into in-memory xarray datasets.

mesh_datasets_from_xdmf

mesh_datasets_from_xdmf(xdmf_path, overwrite=False)

Return scalar cell and point datasets and cache them as NetCDF files.

Scalars from all cell blocks are concatenated in mesh order. Vector and tensor fields are omitted. Datasets use (time, cell) or (time, point) dimensions, including single-item and empty meshes. Time steps must share a scalar schema. Both newly generated and cached datasets are fully loaded; no open file handles are returned. Use overwrite=True after modifying source data.

Parameters:

Name Type Description Default
xdmf_path Path

Fixed-mesh XDMF time series.

required
overwrite bool

Regenerate the adjacent _cells.nc and _points.nc caches.

False

Returns:

Type Description
tuple[Dataset, Dataset]

Cell and point datasets, in that order.

Raises:

Type Description
ValueError

The time series is empty or its scalar schema changes.

mesh_datasets_from_xdmf_dir

mesh_datasets_from_xdmf_dir(xdmf_dir, overwrite=True, *, max_workers=None)

Cache scalar datasets using a bounded number of worker processes.

Parameters:

Name Type Description Default
xdmf_dir Path

Directory containing XDMF time series.

required
overwrite bool

Whether to regenerate existing caches.

True
max_workers int | None

Positive worker limit. Defaults to available CPUs minus one, bounded by the number of files. One worker runs without a process pool.

None

Raises:

Type Description
ValueError

The worker limit is not positive.

Compressed NetCDF

Write and read NetCDF datasets with compression decided in one place.

Simulation histories are large: one uncompressed cell dataset of a single run measured 70 MB where the same float32 arrays with deflate and the byte-shuffle filter took 13 MB. NetCDF3, which :mod:scipy writes, has no compression at all, so every dataset here goes through the HDF5-backed h5netcdf engine.

Compression is lossless; the stored dtypes are unchanged. Reading accepts both layouts so a dataset written before compression stays readable.

write_netcdf

write_netcdf(dataset, path)

Write one dataset compressed, leaving the caller's object unchanged.

load_netcdf

load_netcdf(path, **kwargs)

Read a dataset into memory, accepting a legacy uncompressed NetCDF3 file.

open_netcdf

open_netcdf(path, **kwargs)

Open a dataset lazily, accepting a legacy uncompressed NetCDF3 file.

netcdf_encoding

netcdf_encoding(dataset)

Request deflate and shuffle for every array HDF5 can chunk.

HDF5 applies a filter only to a chunked dataset, so a zero-dimensional or empty variable is left out: asking for compression on one is an error rather than a no-op. Non-numeric variables are also left out.