Toolboxes is a sub-package where useful Python modules contributed by users are stored.
Utilities
Information
This package contains various scripts and helper functions.
Receiver identity and numbering
Public receiver numbering follows construction order, not alphabetical Names.
Merge and SEG-Y/SEG-2/DT1 collection match receiver identities across files;
--receiver N selects N in the first file and follows that receiver in later
files. --trace-group name:label selects by unique Name. Ambiguous legacy
multi-receiver files fail rather than silently mix traces. See
Receiver numbering and cross-version processing for the schema and migration policy.
MATLAB users can resolve a unique label with
gprmax_receiver_path(file, name, grid) or pass ReceiverName to
plot_Ascan / plot_Bscan. Numeric paths remain file-local. The legacy
interactive converter accepts only single-receiver files.
Package contents
HPC
This folder contains scripts to assist with running gprMax on high-performance computing (HPC) systems.
MATLAB
The MATLAB folder contains a general reader for the complete gprMax HDF5
output hierarchy and a converter to MATLAB v7.3 MAT files. Add the folder to
the MATLAB path and read an output without first converting it:
addpath("gprMax/toolboxes/Utilities/MATLAB")
free_space = gprmax_read_h5("antenna_free_space.h5");
Ez = free_space.data.rxs.rx1.Ez;
dt = free_space.header.dt;
S11 = free_space.data.ports.feed.S11;
gprmax_read_h5 recursively supports receiver and source histories, ports,
S-parameter studies, NTFF, SAR/radiometry, subgrids, and other groups without
hard-coding those schemas. It reconstructs h5py complex datasets as native
MATLAB complex arrays and restores multidimensional arrays to gprMax’s HDF5
dimension order. Thus a merged receiver remains (time, trace), an S matrix
remains (frequency, output port, input port), and an NTFF field remains
(frequency, direction). Numeric precision, integer arrays, strings, and
all root/group/dataset attributes are retained.
HDF5 names that are not valid MATLAB fields are made valid and unique. The
name_map and header_name_map members retain the original names and
their MATLAB equivalents. The normal structure is:
result.header common root attributes such as dt and Iterations
result.data recursively mirrored HDF5 groups and datasets
result.metadata attributes and dimensions for every loaded object
result.name_map original HDF5 path to MATLAB field-path mapping
result.info source filename and reader information
gprmax_h5_get resolves an original HDF5 path through this mapping, which
is useful when a user-selected object ID is not itself a valid MATLAB field:
[S11, metadata] = gprmax_h5_get(result, "/ports/feed-1/S11");
Large outputs can be read selectively so unused datasets are not loaded:
ports = gprmax_read_h5("antenna.h5", ...
"Paths", ["/ports", "/eigenmode_ports"]);
Use gprmax_h5_to_mat when a self-contained MAT file is more convenient:
gprmax_h5_to_mat("antenna_free_space.h5")
gprmax_h5_to_mat("antenna_halfspace.h5")
load("antenna_free_space.mat")
load("antenna_halfspace.mat")
Each MAT file contains a variable derived from its input filename, so the two
results above coexist as antenna_free_space and antenna_halfspace.
Invalid filename characters are converted using matlab.lang.makeValidName.
An explicit name and destination can instead be supplied:
gprmax_h5_to_mat("model.h5", ...
"OutputFile", "free_space_result.mat", ...
"VariableName", "free_space", ...
"Paths", ["/rxs", "/ports"]);
Several HDF5 files can either be converted to separate MAT files in one call,
or collected under <variable>.runs in one MAT file:
files = ["free_space.h5", "dry_soil.h5", "wet_soil.h5"];
gprmax_h5_to_mat(files)
gprmax_h5_to_mat(files, ...
"OutputFile", "soil_study.mat", ...
"VariableName", "soil_study");
Existing MAT files are not replaced unless "Overwrite", true is given.
The converter uses MATLAB v7.3 because classic MAT files have restrictive size
limits. Conversion nevertheless materialises the selected arrays in memory;
for very large snapshots or dense volumetric outputs, select only the required
paths or continue to access HDF5 directly.
The A-scan and B-scan plotters are reusable functions built on the same reader. With no arguments they retain the interactive file-picker workflow. They also return the exact raw values and physical coordinates used in the plot:
[figures, traces] = plot_Ascan("model.h5", ...
"Receiver", 1, ...
"Outputs", "Ez", ...
"FFT", true);
Receiver dataset SampleInterval and TimeSampleOffset metadata are used
to construct the physical time axis, including half-step magnetic-field
timing. Use "Grid", "/subgrids/fine" for receivers belonging to a
subgrid. The optional Path selects an arbitrary time-domain group instead,
allowing a voltage-port, transmission-line, or magnetic-frill history to be
plotted with the same function:
[figure_handle, feed] = plot_Ascan("antenna.h5", ...
"Path", "/ports/feed", ...
"Outputs", "Vtotal");
Figures can be rendered without a window and saved reproducibly:
plot_Ascan("model.h5", ...
"Outputs", ["Ex", "Hy"], ...
"Visible", false, ...
"Save", true, ...
"OutputDirectory", "plots");
plot_Bscan expects the modern merged (time, trace) dataset and does
not transpose it again. When retained trace positions are available, its
horizontal axis is the cumulative three-dimensional receiver or terminal
path distance; otherwise it uses trace number. Both receiver fields and real
antenna-terminal voltages are supported:
[figure_handle, field_scan] = plot_Bscan( ...
"survey_merged.h5", "Ez");
[figure_handle, voltage_scan] = plot_Bscan( ...
"antenna_merged.h5", "Vtotal", ...
"Path", "/ports/receive", ...
"OutputFile", "antenna_voltage.png");
The Path option can similarly identify /tls/tl1, /frills/frill1,
or a main-grid/subgrid receiver group. Only real time-domain matrices are
accepted; complex frequency-domain quantities are rejected.
outputfile_converter.m is a legacy exporter to vendor GPR formats and is
unrelated to the general HDF5-to-MAT converter.
Paraview
This folder contains a Python macro to be installed into ParaView. The macro
creates named threshold items for the materials in a gprMax VTKHDF geometry
file. When semantic geometry tags are present, it also creates initially hidden
Tag - <name> threshold items so tagged objects can be viewed independently
of their electromagnetic materials. Sources, receivers, and any exterior PML
regions contained in the selected geometry view are added to the pipeline as
separate objects.
convert_png2h5.py
This module converts discrete colours in a Portable Network Graphics (PNG)
image into a voxel-only HDF5 geometry file and companion versioned JSON
material database. Both files use the current
GeometryObjectsRead/#geometry_objects_read schema. The resulting
geometry is two-dimensional but can be extended by a chosen number of cells
in the z (invariant) direction. Usage from the top-level gprMax directory is:
python -m gprMax.toolboxes.Utilities.convert_png2h5 imagefile dx dy dz
where:
imagefileis the PNG filename, including its path;dx dy dzare the three model spatial discretisations in metres.
There is an optional command line argument:
--zcellsis the number of cells in the z direction (default: one);--output-fileselects the HDF5 destination.
For example create a HDF5 geometry objects file from the PNG image my_layers.png with a spatial discretisation of \(\Delta x = \Delta y = \Delta z = 0.002\) metres, and extending 150 cells in the z-(invariate) direction of the model:
python -m gprMax.toolboxes.Utilities.convert_png2h5 \
my_layers.png 0.002 0.002 0.002 --zcells 150
The image is displayed interactively. Single-click each colour that should
become a material and then close the image. Selection order defines compact
material indices, while the selected RGB/RGBA values are retained in the JSON
metadata. Unselected pixels are stored as -1 and therefore leave the
existing model material unchanged when the geometry is imported. Use a
palette-like image without anti-aliasing or colour gradients: every distinct
channel value is a different colour.
For the example above the utility writes my_layers.h5 and
my_layers_materials.json. The HDF5 file contains /data and stable
/material_keys and records the companion database identity. Image colours
do not determine electromagnetic properties, so the generated JSON entries
deliberately contain null constitutive values. Edit every selected material to
supply relative permittivity, electric conductivity in S/m, relative
permeability, and magnetic conductivity in S/m before running gprMax. Existing
edited JSON values are preserved when the same colour mapping is regenerated;
a changed mapping is rejected rather than silently detaching the database from
its geometry.
After completing the JSON file, import the image geometry with, for example:
#geometry_objects_read: 0 0 0 my_layers.h5 my_layers_materials y
or with the Python API:
scene.add(gprMax.GeometryObjectsRead(
p1=(0, 0, 0),
geofile="my_layers.h5",
material_database="my_layers_materials",
averaging="y",
))
The optional averaging choice belongs to GeometryObjectsRead rather than
the converter. Use "y" for smoothable dielectric interfaces and "n"
when exact staircased voxel membership is required. The imported resolution
must match the simulation resolution.
get_host_spec.py
This module prints information about the host machine capabilities for OpenMP, CUDA, OpenCL, and Apple Metal. It is safe to import; the hardware probing is performed only when the module is run as a command.
outputfiles_merge.py
gprMax produces a separate output file for each trace (A-scan) in a B-scan. This module combines real, time-domain receiver and antenna-terminal traces into a single two-dimensional HDF5 file and can remove the separate files afterwards. Main-grid and subgrid outputs are supported. The files must have matching output components, data types, metadata, iteration counts, and time steps. Usage from the top-level gprMax directory is:
python -m gprMax.toolboxes.Utilities.outputfiles_merge basefilename --remove-files
where:
basefilenameis the base name file of the output file series, e.g. formyoutput1.h5,myoutput2.h5the base file name would bemyoutputremove-filesis an optional argument (flag) that when given will remove the separate output files after the merge.
The destination must not be an input file, including symbolic-link and
hard-link aliases. The merger validates all inputs and writes to a temporary
sibling location before atomically publishing the completed result. A failed
write preserves an existing destination and all inputs; --remove-files
is applied only after successful publication.
The columns of every merged receiver dataset correspond to the naturally
ordered input files. Per-trace physical and grid positions for receivers and
position-bearing sources are retained below /trace_metadata (and below
the corresponding subgrid’s trace_metadata group). The original
single-position receiver or port attributes are retained for compatibility
and refer to the first trace. The merged grid attributes include ntraces
and identify the content as
real_time_domain_receivers_and_terminal_voltages.
This is deliberately an A-scan-to-B-scan utility. It merges the ordinary
receiver components Ex, Ey, Ez, Hx, Hy, Hz, Ix,
Iy, and Iz. It also merges the authoritative total terminal voltage
Vtotal from voltage-source and rational-network ports under /ports,
transmission-line feeds under /tls, and magnetic-frill feeds under
/frills. This permits antenna B-scans to use a physical terminal response
without introducing a theoretical point receiver. A passive receiving antenna
can therefore be represented by its normal zero-excitation port and its
Vtotal response.
The source types use different internal Yee-time history lengths. The merger
retains the physical N-1 voltage samples of resistive/hard voltage-source
ports, all N rational-network and transmission-line samples, and the first
N magnetic-frill samples (the frill’s extra stored endpoint is not a
physical FDTD output sample). Sample interval, physical time offset, quantity,
and volt units are written on every merged voltage dataset.
Frequency-domain products such as S-parameters, impedance, spectra, NTFF results, SAR/radiometry results, snapshots, and study data are not copied. A file series with neither receiver nor terminal-voltage A-scans is rejected rather than producing an empty or misleading file. Complex data, mixed precision, and an already merged two-dimensional dataset are also rejected.
The resulting voltage B-scan can be plotted directly. For example:
python -m gprMax.toolboxes.Plotting.plot_Bscan antenna_merged.h5 Vtotal \
--trace-group ports/receive
The trace group can similarly be tls/tl1 or frills/frill1.
Physical trace timing and native source-buffer lengths are also shared by the
SEG-Y/SEG-2/DT1 collectors and Python port plotting. Frill Vinc, Vtotal
and Itot use only the first Iterations samples; their extra allocation
endpoint is not exported or plotted. Frill current is already averaged onto
the integer voltage lattice, so its offset is zero, unlike a receiver loop
current. Native terminal time axes and group metadata are validated, and
subgrid histories use the owning grid’s interval. Malformed time axes are
rejected rather than replaced with a guessed root-grid axis.
outputfiles_segy.py
This module exports a naturally ordered series of gprMax A-scans as a SEG-Y revision 2.1 file by default, with an optional revision-1 GPR compatibility profile. It writes one selected receiver component per trace, preserves the source and receiver coordinates from every model run, and stores samples as big-endian IEEE 32-bit floating point values. For example:
python -m gprMax.toolboxes.Utilities.outputfiles_segy myoutput Ez
This reads myoutput1.h5, myoutput2.h5, and so on, and writes
myoutput_Ez.sgy. The principal options are:
--receiver 2selects receiver 2 (the default is receiver 1)--source srcs/src2selects the source whose position is written when a model contains more than one source--trace-group tls/tl1selects a position-bearing group other than an ordinary receiver, allowing a real time-domain voltage such asVtotalto be exported--grid subgrids/fineselects receiver and source data in a subgrid--output-file survey.sgychooses the output name--line-number 15sets the SEG-Y line number--profile gprwrites the legacy GPR convention used by software such as GeoLitix, instead of the standards-compliant revision 2.1 default--overwritepermits replacement of an existing SEG-Y file
The original, separate A-scan files must still exist. Although the standard merged gprMax output now retains per-trace source and receiver positions, the interchange exporters deliberately consume original one-dimensional A-scans so that every exported trace is validated independently.
Normal FDTD time steps are much shorter than one microsecond and cannot be represented by SEG-Y’s legacy integer-microsecond sample-interval fields. The exporter therefore follows revision 2.1 and stores the exact interval in the extended IEEE 64-bit sample-interval field in binary-header bytes 3273–3280; the legacy field is zero unless the interval is exactly representable. Software limited to SEG-Y revision 1 may consequently reject the sampling metadata or require a non-standard workaround. The physical time of sample zero is recorded in the textual header because the standard trace delay fields cannot represent the sub-nanosecond Yee-grid time offsets used by gprMax.
Many GPR programs instead use a legacy adaptation in which the ordinary SEG-Y interval fields contain integer picoseconds, despite those fields being defined as microseconds by the seismic standard. GeoLitix describes its output as using the common GPR SEG-Y format for this reason. For compatibility, use:
python -m gprMax.toolboxes.Utilities.outputfiles_segy myoutput Ez --profile gpr
This profile writes SEG-Y revision 1, generic live/production traces, and the
picosecond interval convention expected by legacy GPR readers. If the FDTD
time step is not an integer number of picoseconds, the exporter linearly
resamples each trace to the nearest integer-picosecond interval. The original
and exported intervals are recorded in the textual header. Resampling is never
performed by the default standard profile. The GPR convention is useful
for software interoperability but is intentionally not described as compliant
with the SEG-Y seismic standard.
Coordinates are written in metres with a scalar of -10000 (0.1 mm
precision). The source and receiver z coordinates are written as elevations.
The trace samples must be real, uniformly sampled time-domain fields, currents,
or voltages. Complex or frequency-domain quantities such as S11 and
Zin are deliberately rejected. Samples retain their native SI quantity and
are not amplitude normalised; the selected quantity and its units are recorded
in the textual header. This is a synthetic-data interchange export, not a claim
that a field component is a calibrated instrument voltage.
A complete 151-trace 2D TM example containing four buried PEC metal bars is
provided in gprMax/toolboxes/Utilities/examples/four_metal_bars.in. In the 2D
model the circular cross-sections extend through the invariant direction and
therefore represent bars rather than finite pipes. The 0.60 m scan aperture
provides visible flanks for all four hyperbolic responses. It can be run and
exported with:
python -m gprMax gprMax/toolboxes/Utilities/examples/four_metal_bars.in \
-n 151 --geometry-fixed
python -m gprMax.toolboxes.Utilities.outputfiles_segy \
gprMax/toolboxes/Utilities/examples/four_metal_bars Ez
The input also requests a voxel geometry view named
four_metal_bars.vtkhdf. To generate and inspect only that file before
running the complete scan, use:
python -m gprMax gprMax/toolboxes/Utilities/examples/four_metal_bars.in \
--geometry-only
The resulting survey file contains four hyperbolic bar responses and can be opened directly by a revision-2-aware SEG-Y reader. Export the SEG-Y file before removing the individual A-scan HDF5 files.
For GeoLitix and other revision-1 GPR software, append --profile gpr to
the export command.
outputfiles_seg2.py
This module exports the same naturally ordered gprMax A-scan series in
SEG-2 revision 1.
SEG-2 was designed for shallow seismic and digital-radar data. Unlike the
legacy SEG-Y interval fields, its SAMPLE_INTERVAL trace keyword is a
floating-point value in seconds. The exporter can therefore retain a normal
FDTD time step exactly without resampling. For example:
python -m gprMax.toolboxes.Utilities.outputfiles_seg2 myoutput Ez
This writes myoutput_Ez.sg2 using little-endian IEEE 32-bit floating-point
samples. Source and receiver positions are written in metres for every trace,
and the component, native SI unit, source path, and physical time of sample
zero are retained as SEG-2 free-format metadata. The options --receiver,
--source, --trace-group, --grid, --output-file, and
--overwrite have the same meanings as for outputfiles_segy.py.
SEG-2 has no universal controlled vocabulary for all GPR metadata. Standard
keywords such as SAMPLE_INTERVAL, RECEIVER_LOCATION,
SOURCE_LOCATION, and TRACE_TYPE RADAR_DATA are accompanied by
explicit GPRMAX_* metadata. Readers are expected to retain unrecognised
free-format strings, but applications may display only a subset of them.
outputfiles_dt1.py
This module exports a gprMax A-scan series as the paired Sensors & Software
.DT1 data and .HD header files used by many GPR-processing programs:
python -m gprMax.toolboxes.Utilities.outputfiles_dt1 myoutput Ez \
--nominal-frequency 1000
This writes myoutput_Ez.DT1 and myoutput_Ez.HD. The optional nominal
frequency is in MHz; its default value of zero means unspecified. Source and
receiver coordinates are stored in every binary trace header. The scalar
survey position is the cumulative three-dimensional receiver path length, so
non-x-directed survey lines are not collapsed. The options --receiver,
--source, --trace-group, --grid, --output-file, and
--overwrite have the same meanings as for the other exporters.
DT1 stores samples as signed 16-bit integers. The exporter therefore uses one
symmetric scale for the complete survey, maps the largest absolute value to
32767, and records GPRMAX COUNT SCALE and the reconstruction rule
SI_VALUE = INTEGER_COUNT * GPRMAX_COUNT_SCALE in the HD file. This keeps
relative amplitudes between traces but introduces at most half of one count
of quantisation error. Software unaware of the gprMax extension will show the
integer counts, which remain suitable for conventional GPR processing. SEG-Y
or SEG-2 should be preferred when native floating-point amplitudes are
required.
DT1/HD is a vendor format rather than an open interchange standard. The implementation follows the commonly supported 128-byte trace header layout and has been checked with the open-source GPRPy reader. Exact gprMax sampling and Yee-grid timing metadata are added after the conventional HD entries, so readers that parse only the established fields remain compatible.
The four-metal-bar model shown in the SEG-Y section can be exported to either additional format without rerunning it:
python -m gprMax.toolboxes.Utilities.outputfiles_seg2 \
gprMax/toolboxes/Utilities/examples/four_metal_bars Ez
python -m gprMax.toolboxes.Utilities.outputfiles_dt1 \
gprMax/toolboxes/Utilities/examples/four_metal_bars Ez \
--nominal-frequency 1000