Utilities

HDF5 Field Dump Reader

Reads the HDF5 files written by any field dump box, see Field Dump HDF5 File Format for the file format itself.

class openEMS.utilities.HDF5Dump(filename)

Reader for an openEMS HDF5 field dump file.

Opens the file, reads the (cheap) metadata up front and keeps the file open for subsequent field reads. All metadata – the dump type, whether the file holds time or frequency domain data, the number of samples and the mesh size – is available before any field data is read.

The region of interest is configured on the object and then applies to every field access. SetPlane, SetRange and SetSampling restrict the read to a plane, a sub-range or a sub-sampled grid; the selection is passed down to HDF5 so that only the requested data is read from disk. Field data is always returned in the natural, x-inner order (3, Nx, Ny, Nz) regardless of how the file is stored on disk.

Parameters:
filenamestr or h5py.File

Path to the dump file, or an already open file. An already open file is not closed by this class.

See also

openEMS.sar_utils.readSAR

convenience reader for SAR result files

Examples

>>> with HDF5Dump('Ef.h5') as dump:
...     print(dump)
...     dump.SetPlane('z', pos=10e-3)          # nearest z-line to 10 mm
...     dump.SetSampling(2, 2, 1)              # every other x and y line
...     for freq, field in dump.IterFD():
...         pass

A time domain dump can be evaluated at a frequency directly; the DFT is then done on the fly, holding only one timestep in memory at a time:

>>> with HDF5Dump('Et.h5') as dump:
...     E = dump.GetFieldAtFrequency(2.4e9)
FREQ_RTOL = 1e-06

Relative tolerance when matching a frequency requested from GetFieldAtFrequency against the frequencies stored in the file.

file

the open h5py.File, for anything not wrapped here (e.g. the /CellData and /CellWidth groups of a raw SAR dump)

Close()

Close the file, unless it was handed in already open.

GetDumpTypeName()

Human readable name of the dump type.

IsTD()

True if the file holds time domain data.

IsFD()

True if the file holds frequency domain data.

IsVector()

True for a vector field dump, False for a scalar one (e.g. SAR).

GetNumTimesteps()

Number of recorded timesteps (0 for an FD-only dump).

GetNumFrequencies()

Number of recorded frequencies (0 for a TD-only dump).

GetTimes()

The simulation times of the recorded timesteps, in s.

ResetRegion(ny=None)

Drop plane/range/sampling settings and read the full dump again.

Parameters:
nyint or str, optional

Reset only this direction, given as 0/1/2 or a coordinate name. By default all three directions are reset.

NearestIndex(ny, coord)

Index of the mesh line closest to coord along direction ny.

Parameters:
nyint or str

Direction, as 0/1/2 or a coordinate name (‘x’, ‘rho’, …).

coordfloat

Coordinate in SI units, i.e. metres for lengths and radians for angles – the same units as GetMesh()['lines'].

SetPlane(ny, pos=None, idx=None)

Restrict all field reads to a single plane normal to ny.

The plane axis collapses, so a 3D vector dump then yields data of shape (3, N1, N2) instead of (3, Nx, Ny, Nz).

Parameters:
nyint or str

Normal direction, as 0/1/2 or a coordinate name (‘x’, ‘rho’, …).

posfloat, optional

Position in SI units; the nearest mesh line is used.

idxint, optional

Mesh line index. Exactly one of pos and idx must be given.

There is only ever one plane: setting a plane for a different
direction replaces the previous one, so switching the slice
orientation needs no reset. Ranges and sampling on the other
directions are kept. It raises if *this* direction already has a
range set; use ``ResetRegion(ny)`` to clear it first.
SetLine(ny, pos=None, idx=None)

Restrict all field reads to a single line along direction ny.

The two directions perpendicular to ny collapse, so a 3D vector dump yields data of shape (3, N) instead of (3, Nx, Ny, Nz).

Parameters:
nyint or str

Direction the line runs along, as 0/1/2 or a coordinate name.

possequence of three floats, optional

Position in SI units for each direction; the nearest mesh line is used. The entry for the line direction ny must be None.

idxsequence of three ints, optional

The same as mesh line indices. Exactly one of pos and idx must be given.

The entry for each direction is given by its **position in the
sequence, so there is no ambiguity about the order:**
``SetLine(‘y’, idx=(3, None, 5))`` is a line along y at x-index 3 and
z-index 5.
The two perpendicular directions always collapse, replacing whatever
was set for them. For the line direction itself, a setting that would
leave fewer than two lines – a plane normal, or a previous line – is
reset to the full extent, while an existing range of two or more lines
is kept. Sampling is never changed.

Examples

>>> dump.SetLine('x', idx=(None, 3, 5))       # along x at y=3, z=5
>>> dump.SetLine('z', pos=(0.0, 1e-3, None))  # along z at x=0, y=1 mm
SetRange(ny, start=None, stop=None, idx_start=None, idx_stop=None)

Restrict all field reads to a sub-range along direction ny.

Parameters:
nyint or str

Direction, as 0/1/2 or a coordinate name (‘x’, ‘rho’, …).

start, stopfloat, optional

Range limits in SI units. The nearest mesh lines are used and both limits are inclusive.

idx_start, idx_stopint, optional

Range limits as mesh line indices, half open as usual in Python (idx_stop is not included). Cannot be combined with start/stop.

Calling `SetRange` again for the same direction replaces the range. It
raises if that direction already has a plane set; use
``ResetRegion(ny)`` to clear it first.
SetSampling(*factors)

Sub-sample the field data by the given step in each direction.

Accepts either a single factor applied to all three directions, or one factor per direction, e.g. SetSampling(2) or SetSampling(2, 2, 1). Sub-sampling is applied by HDF5 while reading, it does not interpolate.

GetMesh(region=False)

Return the mesh of the dump.

Parameters:
regionbool, optional

If True, return only the mesh lines covered by the currently configured region and sampling, i.e. the lines matching the field data returned by the getters. A plane direction then yields a single-element array.

Returns:
meshdict
  • lines : list of the three coordinate vectors, in SI units, i.e. metres for lengths and radians for angles

  • names : the corresponding coordinate names, e.g. ['x','y','z']

  • type : 0 –> Cartesian, 1 –> cylindrical, 2 –> spherical

  • scaling : the simulation length unit in metres (e.g. 1e-3 for a mm mesh); divide lines by it to get the drawing units

GetFieldAtIndex(f_idx=None, t_idx=None, component=None)

Read one field sample, addressed by its index in the file.

Parameters:
f_idxint or str, optional

Frequency index, or a dataset name such as 'f0'.

t_idxint or str, optional

Position of the timestep in the file, or a dataset name such as '000100'. Exactly one of f_idx and t_idx must be given.

componentint or str, optional

Read only this vector component; by default all three are read.

Returns:
datandarray

Shape (3, Nx, Ny, Nz) for a vector dump, (Nx, Ny, Nz) for a scalar one, reduced by the configured region, sampling and component. Frequency domain data is complex, time domain data is real.

GetFieldAtFrequency(freq, component=None)

Read the field at a given frequency, in Hz.

If the file holds frequency domain data, the matching dataset is read directly; the frequency must match one stored in the file to within FREQ_RTOL. Otherwise the frequency is computed from the time domain data by an on-the-fly DFT, which reads every timestep but holds only one of them in memory at a time.

Parameters:
freqfloat

Frequency in Hz.

componentint or str, optional

Read only this vector component; by default all three are read.

IterFD(component=None)

Iterate over all frequency domain samples.

Yields:
(freq, data)tuple of float and ndarray

The frequency in Hz and the field data, see GetFieldAtIndex.

IterTD(component=None)

Iterate over all recorded timesteps.

Yields:
(time, data)tuple of float and ndarray

The simulation time in s and the field data, see GetFieldAtIndex.

GetAttributes(f_idx=None, t_idx=None)

Collect the attributes applying to one sample, without reading it.

Attributes are taken from three levels in order of increasing precedence: the file root, the /FieldData/{FD,TD} group and the dataset itself. Later levels overwrite earlier ones when the same key appears at several levels; in particular the frequency array of the FD group is overwritten by the scalar frequency of the dataset.

Signal Processing

openEMS.utilities.DFT_time2freq(t, val, freq, signal_type='pulse')
openEMS.utilities.check_mode_purity(label, signal, purity, threshold=0.99, sig_frac=0.01)

Assert mode purity > threshold where the signal exceeds sig_frac * peak.

Parameters:
labelstr

Descriptive name used in the assertion message.

signalarray

Time-domain signal amplitude (column 1 of probe file).

purityarray or None

Mode purity time series (column 2 of probe file), or None if unavailable.

thresholdfloat

Minimum acceptable mode purity (default 0.99 = 99 %).

sig_fracfloat

Ignore time steps where |signal| < sig_frac * max(|signal|).

Notes

Purity can be negative when the wave travels in the opposite direction (e.g. the receive port seeing the transmitted wave), so abs(purity) is used.

openEMS.utilities.Check_Array_Equal(a, b, tol, relative=False)