Skip to content

Instantly share code, notes, and snippets.

@ZedThree
Created May 27, 2015 08:58
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZedThree/8ee244a42717e0037010 to your computer and use it in GitHub Desktop.
Save ZedThree/8ee244a42717e0037010 to your computer and use it in GitHub Desktop.
An example of writing 3D time series data to an XMF file which references data in an accompanying HDF5 file (output.h5)
from xml.etree.ElementTree import Element, SubElement
from xml.etree import ElementTree
from xml.dom import minidom
def prettify(elem):
"""Return a pretty-printed XML string for the Element.
"""
rough_string = ElementTree.tostring(elem, 'utf-8')
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent=" ")
def write_xdmf(self, filename='output.xdmf', timesteps=[0]):
"""Write an XDMF file to accompany the HDF5 data file.
"""
# Get the size of the datasets to write
dims_x = str(self.density.shape[0])
dims_y = str(self.density.shape[1])
dims_z = str(self.density.shape[2])
dims_t = str(self.density.shape[3])
dims = np.transpose(self.density).shape
# Topology dimensions do not include time dimension
dims_topol = "{0} {1} {2}".format(dims_z, dims_y, dims_x)
# The full dimensions of the data
dims_data = "{0} {1} {2} {3}".format(dims_t, dims_z, dims_y, dims_x)
# The dimensions of a single slab
dims_slab = "1 " + dims_topol
# Create the basic structure
root = Element('Xdmf')
root.set('version', '2.2')
domain = SubElement(root, 'Domain')
# The geometry. This will be referenced by each timestep, rather
# than inserting it into each one
geometry = SubElement(root, 'Geometry', {'GeometryType':"VXVYVZ"})
x_data = SubElement(geometry, 'DataItem', {'Dimensions':dims_x,
"NumberType":"Float",
"Precision":"8",
"Format":"HDF5"})
x_data.text = "output.h5:/data/3D/fields/x"
y_data = SubElement(geometry, 'DataItem', {'Dimensions':dims_y,
"NumberType":"Float",
"Precision":"8",
"Format":"HDF5"})
y_data.text = "output.h5:/data/3D/fields/y"
z_data = SubElement(geometry, 'DataItem', {'Dimensions':dims_z,
"NumberType":"Float",
"Precision":"8",
"Format":"HDF5"})
z_data.text = "output.h5:/data/3D/fields/z"
# Create the temporal collection and insert the time data
# Future: use hyperslab?
# Number of timesteps to write
time_dims = str(len(timesteps))
time_grid = SubElement(domain, 'Grid', {'Name':'DensityGrid',
'GridType':'Collection',
'CollectionType':'Temporal'})
time = SubElement(time_grid, 'Time', {'TimeType':'List',
'Dimensions':time_dims})
time_data = SubElement(time, 'DataItem', {'NumberType':'Float',
'Dimensions':time_dims,
'Format':'XML'})
time_data.text = np.array_str(self.T[timesteps]).strip('[]').replace(",","")
# Add all the timesteps
for step in timesteps:
grid = SubElement(time_grid, 'Grid',
{'Name':'Structred Grid',
'GridType':'Uniform'})
topology = SubElement(grid, 'Topology',
{'TopologyType':'3DRECTMesh',
'Dimensions':dims_topol})
geometry = SubElement(grid, 'Geometry',
{"Reference":"/Xdmf/Geometry[1]"})
density = SubElement(grid, "Attribute",
{"Name":"density",
"AttributeType":"Scalar",
"Center":"Node"})
density_slab = SubElement(density, "DataItem",
{"ItemType":"HyperSlab",
"Dimensions":dims_slab,
"Type":"HyperSlab"})
density_extent = SubElement(density_slab, "DataItem",
{"Dimensions":"3 4",
"Format":"XML"})
density_extent.text = str(step) + " 0 0 0\n1 1 1 1\n" + dims_slab
density_data = SubElement(density_slab, "DataItem",
{"Format":"HDF",
"NumberType":"Float",
"Precision":"8",
"Dimensions":dims_data})
density_data.text = "output.h5:/data/3D/fields/density"
self.root = root
with open(filename,'w') as f:
f.write(prettify(self.root))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment