README.md (4377B)
1 # TEM Loader 2 3 A QGIS 3.40+ plugin for loading Time-Domain Electromagnetic (TEM) geophysical inversion XYZ files as styled 3D vector layers. 4 5 ## Overview 6 7 TEM Loader parses XYZ inversion model files and loads them into QGIS as three layer types: 8 9 - **Points** — surface terrain positions with survey line labels 10 - **DOI** — depth-of-investigation points at depth 11 - **Layers** — resistivity model layers as vertical 3D line segments 12 13 Each file gets its own layer group. Layers are styled with pre-built QML styles and support the QGIS Elevation Profile tool for profile visualization. 14 15 ## Requirements 16 17 - QGIS 3.40.0 or later (up to 4.1.0) 18 - Python 3 (bundled with QGIS) 19 20 ## Installation 21 22 1. Download `tem_loader.zip` from the [releases page](https://gitlab.com/qgeomodel/qgis-tem-loader/-/releases) or build it yourself (see below). 23 2. In QGIS: **Plugins > Manage and Install Plugins > Install from ZIP**. 24 3. Select the zip file and click **Install Plugin**. 25 26 ## Usage 27 28 1. Open a QGIS project. 29 2. Go to **Plugins > TEM Loader > Load TEM XYZ files…**. 30 3. Select one or more `.xyz` inversion files. 31 4. In the import options dialog, optionally enable **Adjust vertical position to digital elevation model** and choose a raster layer from the current project. When enabled, surface elevations are sampled from band 1 of the selected DEM; points outside the DEM keep their source elevation and emit a console warning. 32 5. If the file metadata declares an EPSG code, imported layers use that CRS; otherwise the loader falls back to the project CRS, then to EPSG:4326. 33 6. A GeoPackage (`.gpkg`) is written beside each source file with `points`, optional `doi`, and `layers` layers, and the corresponding layers are added to the project with `points` above `doi` above `layers`. 34 7. Invalid or malformed `.xyz` inputs are rejected with explicit validation errors, and when multiple files are selected the loader continues with the remaining files while reporting the failing input filename. 35 36 ## XYZ File Format 37 38 Input files are whitespace-delimited with optional `/`-prefixed metadata lines. The loader currently supports these export variants: 39 40 - **TEMImage** exports with `Line`, `StationNo`, `Z`, `DOI`, `DataResidual`, `NumLayers`, `Res_*`, and `Thick_*` 41 - **Aarhus Workbench** exports with `LINE_NO`, `ELEVATION`, `RECORD`, `RESDATA`, `RHO_*`, `THK_*`, `DEP_TOP_*`, `DEP_BOT_*`, and `DOI_STANDARD` 42 - **ATEM SCI Workbench** wide exports with `FID`, `LINE`, `E`, `N`, `DEM`, `RESI1`, `DOI`, `ResNNN`, `ResNNN_doi`, and `ElevNNN` 43 44 For Aarhus Workbench files, the plugin normalizes fields into the existing output schema by: 45 46 - accepting either `X` / `Y` or `UTMX` / `UTMY` as source coordinate headers 47 - deriving `StationNo` from `LINE_NO` and `RECORD` as `LINE_RECORD`, for example `1_00001` 48 - mapping `DOI_STANDARD` to the output `DOI` field 49 - using `ELEVATION` as the surface Z value 50 - using `DEP_TOP_*` and `DEP_BOT_*` when building layer geometry 51 52 For ATEM SCI Workbench wide files, the plugin normalizes fields by: 53 54 - mapping `E` / `N` to output coordinates 55 - using `DEM` as the surface Z value 56 - mapping `RESI1` to `DataResidual` 57 - deriving `StationNo` from `LINE` and `FID` as `LINE_FID`, for example `100101_00001` 58 - mapping `DOI` as a depth below `DEM` 59 - using `ResNNN` for model resistivity and `ElevNNN` as layer-top elevations 60 - inferring a finite bottom elevation for the final layer so all model resistivity columns render as 3D segments 61 62 Legacy TEMImage files with an extra leading index or project column are handled automatically. 63 64 ## Development 65 66 ```sh 67 make lint # run flake8 68 make test # run the unittest suite 69 make verify # run lint and tests 70 make package # build tem_loader.zip for installation 71 make clean # remove the zip 72 ``` 73 74 `core.py` (XYZ parsing and CSV helper output) has no QGIS dependency and is fully unit-testable. `tem_loader.py` (GeoPackage writing and layer loading) requires a running QGIS instance and is verified with mocked unit tests plus manual QGIS checks. 75 76 ## References 77 78 - Test data from Salling from Madsen et al 2026: 79 - publication DOI: <https://doi.org/10.1002/gdj3.70067> 80 - data DOI: <https://doi.org/10.5281/zenodo.16894038> 81 82 ## Repository 83 84 - Source: <https://gitlab.com/qgeomodel/qgis-tem-loader> 85 - Issues: <https://gitlab.com/qgeomodel/qgis-tem-loader/issues> 86 - Author: Anders Damsgaard (<andam@geus.dk>)