THz Image Explorer - An Interactive Cross-Platform Open-Source THz Image Analysis Tool

THz Image Explorer - An Interactive Cross-Platform Open-Source THz Image Analysis Tool - Published in JOSS (2025)

https://github.com/unibe-icelab/thz-image-explorer

Science Score: 93.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 1 DOI reference(s) in JOSS metadata
  • Academic publication links
    Links to: joss.theoj.org
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
    Published in Journal of Open Source Software

Keywords

analysis rust thz thz-tds
Last synced: 4 months ago · JSON representation

Repository

THz Image Explorer is an application for THz time-domain image analysis.

Basic Info
  • Host: GitHub
  • Owner: unibe-icelab
  • License: gpl-3.0
  • Language: Rust
  • Default Branch: main
  • Homepage:
  • Size: 51 MB
Statistics
  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • Open Issues: 6
  • Releases: 6
Topics
analysis rust thz thz-tds
Created over 1 year ago · Last pushed 4 months ago
Metadata Files
Readme Changelog License

README.MD

THz Image Explorer - An Interactive Cross-Platform Open-Source THz Image Analysis Tool

status Deployment SLOCs counter GitHub License

“”

THz Image Explorer is an interactive cross-platform open-source tool for analyzing THz time-domain imaging data. Its goal is to make the analysis of THz scans easier and more accessible to researchers by providing a user-friendly interface and a set of powerful features. This Application is written in Rust and the GUI is based on egui and bevy.

Screenshot of the application on macOS 3D render gif

Sample scans of a THz time-domain 2D imaging system can be found in the sample_data directory. The reference.thz corresponds to the l_alanine_sample.thzimg file.


Table of Contents


Features

  • Cross-platform (Linux, macOS, Windows)
  • Interactive 2D and 3D visualization
  • Meta data editing
  • Region of Interest (ROI) selection and comparison
  • Reference dataset support
  • Extensible with custom filters

Installation

Download Pre-built Executables

Binary bundles are available for Linux, macOS, and Windows.

macOS

If you see the message "THz Image Explorer is damaged and cannot be opened.", run:

sh xattr -rd com.apple.quarantine THz\ Image\ Explorer.app

Linux

Install dependencies:

sh sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libssl-dev libasound2-dev libxkbcommon-x11-0 libx11-dev


Compile from Source

  1. Install Rust and Cargo.
  2. Install Cmake.
  3. Install dependencies (Linux only): sh sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libssl-dev pkg-config libx11-dev libasound2-dev libudev-dev libxkbcommon-x11-0 Note: For Fedora and other distributions consult bevy and egui documentation for the required dependencies.
  4. Install bundling tools:
    • Linux/macOS: cargo install cargo-bundle
    • Windows: cargo install cargo-wix
  5. Build:
    • Linux/macOS: cargo bundle --release
    • Windows: cargo wix -p thz-image-explorer

Note: cargo-bundle only supports Linux and macOS. For Windows, use cargo-wix.

macOS Plugin

The DotTHzQLExtension.appex plugin is installed in THz Image Explorer.app/Contents/PlugIns.
Source: DotTHzQL
Requires HDF5 to be installed system-wide.


Usage

Example data is available in the sample_data directory of this repository.

The window is structured with the time domain trace and frequency domain spectrum for the selected pixel (default is 0,0) in the center panel. A different tab showing the optical properties (refractive index and absorption coefficient) can be selected, as well as a tab containing an interactive 3D viewer. The left side-panel contains the intensity plot of the 2D scan along with the meta-data editor. The right side-panel contains the possible filters with configuration settings. A pixel can be (de-)selected by clicking inside the intensity plot. For large scans, it is recommended to down-scale the image. This will average the pixel values in a $2 \times 2$ (or $4 \times 4$ and so on) pixel block, depending on the down-scaling factor. Note that the "Signal" trace in time-domain will still show the raw trace, but the "Signal" spectrum in the FFT plot will show the averaged spectrum of the down-scaled image.

IO

THz Image Explorer is able to load scans in the .thz (dotTHz) format, which are based on the HDF5 standard. This allows the files to also contain meta-data, which will also be displayed by the THz Image Explorer. The meta-data is shown in the file opening dialog on Linux and Windows, and using QuickView on macOS, allowing to easily browse through directories containing multiple scans.

THz Image Explorer supports drag & drop of .thz, .thzimg and .thzswp files.

To comply with the dotTHz standard, the .thzimg file needs to contain two datasets:

  • time axis: 1D, shape (n_t,)
  • data: 3D, shape (n_x, n_y, n_t)

The file should also contain at least the mandatory fields of the meta-data (e.g. user, date, thickness etc.).

The 3D structure can be exported as a .vtu file for further analysis.

A reference file (standard .thz) can be loaded, which is used to compute the optical properties of the sample. The first entry will be used.

Interface

The interface is split into three main sections: Pulse View (main), Optical Properties View and 3D View. New files can be opened either via the Open File Menu in the left panel or by drag & drop of .thz or .thzimg files. A Meta Data editor is located on the left side and a filter configuration panel on the right side. These panels are visible in all three views. The main view shows the time domain trace and frequency domain spectrum of the selected pixel, as well as the 2D intensity plot of the scan. To navigate the plots: - Pan: Left-drag - Horizontal pan: Shift + Scroll - Zoom: Cmd + Scroll - Horizontal zoom: Shift+Cmd + Scroll - Vertical zoom: Option+Cmd + Scroll - Box zoom: Right-drag (on macOS drag with two dingers on the trackpad) - Reset: Double-click

Main View

The Optical Properties View shows the refractive index and absorption coefficient calculated from the selected pixel and the reference scan (this can either be different ROIs, the selected Pixel or the reference file).

Optical Properties View

dotTHz Meta Data Editor

The meta-data editor allows the user to edit the meta-data of the loaded scan. The meta-data is stored in the .thz (or .thzimg, or .thzswp) file. Certain fields are mandatory as per the dotTHz standard, and cannot be deleted. But any further attributes can be added, modified and deleted.

Meta Data Editor

Regions of Interest (ROI)

By holding the Shift key and selecting pixels, a region of interest (ROI) can be selected. This ROI is a convex polygon, which is closed if the last corner is selected reasonably close to the first one (< 5 % of width/height of the image). This ROI can then be saved in the meta-data of the dotTHz file for future analysis. The full averaged scan as well as the averages of all selected ROIs can be displayed in the center plot.

ROI Selection

3D view supports rotation and zoom:

3D View of a scan

Filtering Pipeline

The filtering process is a simple linear pipeline, where the output of one filter is the input of the next filter. On top of the filtering pipeline/panel general settings are located:

  • FFT Log Plot (default: on), which shows the frequency spectrum in logarithmic scale
  • Average in Frequency domain (default: off), which averages the selected pixels (ROI) in frequency domain instead of time domain (after the iFFT). This is useful if averaging in time domain leads to destructive interferences.
  • Downscale Factor (default: 1), which downscales the 2D image by averaging pixel blocks of size Downscale Factor x Downscale Factor

Time Domain Before FFT

Before applying the Fast-Fourier-Transform (FFT), a tilt-compensation can be applied to the time domain trace to compensate any misalignment along the $x$ axis and/or $y$ axis. Additionally, a simple band-pass filter can be applied to exclude secondary peaks.

FFT

To reduce artifacts in frequency domain, a window is multiplied to the time domain signal before applying the Fast-Fourier-Transform (FFT). By default, an adapted Blackman window is applied, but the user can also select other windows:

  • Adapted Blackman (default)
  • Blackman
  • Hanning
  • Hamming
  • FlatTop

The adapted Blackman window is a modified version of the Blackman window, where most of the signal is preserved and only the first and last couple of datapoints are modified.

All windows are defined in math_tools.rs.

Frequency Band Pass Filter

A simple band-pass filter can be applied in fourier space to only display certain frequency bands.

Inverse FFT

The inverse FFT is applied to convert the data from frequency domain back to time domain.

Time Domain After FFT

After converting back to time domain, another band-pass filter can be applied to the time traces.

Deconvolution

The deconvolution filter is an implementation of the Frequency-dependent Richardson-Lucy algorithm.

Custom Filters

Extend the codebase with custom filters:

  1. Create a file in src/filters with a struct implementing the Filter trait.
  2. Attach the file to mod.rs in src/filters.
  3. Implement the required functions (config, filter, ui, etc.).
  4. Derive Clone, Debug, and CopyStaticFields.
  5. Add the #[register_filter] macro to your struct.

Loops requiring heavy computation can be parallelized using the rayon crate. Use the cancellable_loops crate for abortable computations.

Example:

```rust use crate::filters::filter::Filter; use crate::data_container::ScannedImageFilterData; use crate::gui::application::GuiSettingsContainer;

[register_filter]

[derive(Clone, Debug, CopyStaticFields)]

struct ExampleFilter;

impl Filter for ExampleFilter { fn new() -> Self { ExampleFilter }

fn reset(&mut self, time: &Array1<f32>, shape: &[usize]) {
    // Reset any internal state if necessary
}

fn show_data(&mut self, data: &ScannedImageFilterData) {
    // Display any data in the GUI if needed
}

fn filter(
    &mut self,
    input_data: &ScannedImageFilterData,
    gui_settings: &mut GuiSettingsContainer,
    progress_lock: &mut Arc<RwLock<Option<f32>>>,
    abort_flag: &Arc<AtomicBool>,
) -> ScannedImageFilterData {
    // Apply filter logic here
    input_data.clone() // Placeholder, replace with actual filtering logic
}


fn config(&self) -> FilterConfig {
    FilterConfig {
        name: "Example Filter".to_string(),
        description: "Description of the example filter.".to_string(),
        hyperlink: None, // Optional DOI or reference link
        domain: FilterDomain::TimeBeforeFFT, // Specify the domain of the filter
    }
}

fn ui(
    &mut self,
    ui: &mut egui::Ui,
    thread_communication: &mut ThreadCommunication,
    panel_width: f32,
) -> egui::Response {
    // Render filter configuration UI here
}

} ```


PSF File Generation

To run the deconvolution filter, a point spread function (PSF) file is required.

  1. Perform a knife-edge scan and create a .thz file (see sample_data/example_beam_width/).
  2. Install the python dependencies in the scripts directory: pip install -r requirements.txt
  3. Run:

    shell python scripts/generate_psf.py \ --path_x sample_data/example_beam_width/measurement_x/data/1750085285.8557956_data.thz \ --path_y sample_data/example_beam_width/measurement_y/data/1750163177.929295_data.thz

This generates a psf.npz file for deblurring in THz Image Explorer.


Further processing (with Python)

After regions of interest (ROIs) have been selected, they can be saved in the meta-data of the dotTHz file. The coordinates are saved for each ROI with label "ROI {i}" as a list, e.g.:

"ROI 1": [[27.57,34.72],[37.96,23.65],[40.35,32.06],[35.06,37.92]]

while the label of the ROI is saved in the "ROI Labels" meta-data field as a comma-separated list. The file can then be opened with Python using the pydotthz package to further process the data. A Python code snipped for ROI extraction and the PSF generation script can be found in the scripts directory of the repository, be sure to install shapely for python or just run: pip install -r requirements.txt On macOS you might need to install geos first, e.g. via brew install geos.


Tested Platforms

  • macOS 12.4 Monterey x86
  • macOS 10.14.6 Mojave x86
  • Debian 12 (Testing) x86
  • Windows 10 x86

Community Guidelines

We welcome contributions and feedback from the community! Please follow these guidelines:

  1. Contributing to the Software

    • Fork the repository and submit pull requests for new features, bug fixes, or improvements.
    • Please ensure your code follows the existing style and includes relevant documentation.
    • For major changes, open an issue first to discuss your proposal.
  2. Reporting Issues or Problems

    • Use the GitHub Issues page to report bugs, request features, or suggest improvements.
    • Provide as much detail as possible, including steps to reproduce, screenshots, and your operating system.
  3. Seeking Support

    • For general questions or help, open a discussion in the GitHub Discussions section.
    • You may also contact the maintainers via email listed in the relevant publication.

Thank you for helping us improve THz Image Explorer!

Owner

  • Name: IceLab
  • Login: unibe-icelab
  • Kind: organization
  • Location: Switzerland

The Planetary Ice Laboratory "IceLab" focuses on laboratory experiments in the Space and Planetary Science Division at the University of Bern.

JOSS Publication

THz Image Explorer - An Interactive Cross-Platform Open-Source THz Image Analysis Tool
Published
November 07, 2025
Volume 10, Issue 115, Page 8754
Authors
Linus Leo Stöckli ORCID
Space Research & Planetary Sciences Division, University of Bern, Bern, Switzerland
Arnaud Demion ORCID
University of Applied Sciences and Arts Western Switzerland Valais, HES-SO Valais-Wallis, Sion, Switzerland
Nicolas Thomas ORCID
Space Research & Planetary Sciences Division, University of Bern, Bern, Switzerland
Editor
Fruzsina Agocs ORCID
Tags
THz Imaging Data Analysis

GitHub Events

Total
  • Create event: 5
  • Issues event: 3
  • Release event: 4
  • Watch event: 1
  • Delete event: 3
  • Issue comment event: 5
  • Push event: 45
  • Pull request review comment event: 2
  • Pull request review event: 5
  • Pull request event: 5
Last Year
  • Create event: 5
  • Issues event: 3
  • Release event: 4
  • Watch event: 1
  • Delete event: 3
  • Issue comment event: 5
  • Push event: 45
  • Pull request review comment event: 2
  • Pull request review event: 5
  • Pull request event: 5

Issues and Pull Requests

Last synced: 4 months ago

All Time
  • Total issues: 3
  • Total pull requests: 2
  • Average time to close issues: N/A
  • Average time to close pull requests: about 1 hour
  • Total issue authors: 2
  • Total pull request authors: 1
  • Average comments per issue: 0.0
  • Average comments per pull request: 0.0
  • Merged pull requests: 1
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 3
  • Pull requests: 2
  • Average time to close issues: N/A
  • Average time to close pull requests: about 1 hour
  • Issue authors: 2
  • Pull request authors: 1
  • Average comments per issue: 0.0
  • Average comments per pull request: 0.0
  • Merged pull requests: 1
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • hacknus (2)
  • jsdodge (1)
Pull Request Authors
  • hacknus (2)
Top Labels
Issue Labels
Pull Request Labels

Dependencies

.github/workflows/changelog.yml actions
  • tarides/changelog-check-action v2 composite
.github/workflows/deployment.yml actions
  • actions/checkout v4 composite
  • actions/upload-release-asset v1.0.1 composite
.github/workflows/rust.yml actions
  • actions/checkout v4 composite
Cargo.lock cargo
  • 833 dependencies
Cargo.toml cargo
cancellable_loops/Cargo.toml cargo
filter_macros/Cargo.lock cargo
  • heck 0.5.0
  • proc-macro2 1.0.93
  • quote 1.0.38
  • syn 2.0.96
  • unicode-ident 1.0.16
filter_macros/Cargo.toml cargo
scripts/requirements.txt pypi
  • matplotlib *
  • numpy ==1.26.4
  • shapely ==2.0.1
  • thz-deconvolution ==1.0.3
  • tqdm ==4.66.4
.github/workflows/paper.yml actions
  • actions/checkout v4 composite
  • actions/upload-artifact v4 composite
  • openjournals/openjournals-draft-action master composite