Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

Fixed

  • sdk: Metadata attached with Image.with_meta is now carried onto the streaming/write path. Previously the override was only visible through Image.meta, so writing the image (e.g. to ENVI) silently used the source’s original header and dropped changes such as wavelength information.

[1.0.0-beta.4] - 2026-06-12

Added

  • python: Added a StageController.stage_machine property exposing the underlying StageMachine.

Changed

  • control: The stage return move now uses a fixed return velocity of 100 mm/s instead of the configured streaming velocity.

  • package: Updated cargo deny advisory ignores for pyo3 (RUSTSEC-2026-0176 and RUSTSEC-2026-0177); neither advisory is reachable from our usage.

[1.0.0-beta.3] - 2026-06-11

Added

  • python: Image.ufunc now accepts an optional slice_transform callable that maps the requested 2D output plane slice to the input plane slice fetched from the parent, allowing custom operations such as SNV or axis reductions that need the full extent of an axis regardless of the requested output slice. When set, the operation receives the requested output plane slice as a third argument and trims its own output.

  • python: util.operation decorator now forwards a slice_transform argument for ergonomic use of the new capability.

  • docs: Added a new section to the “custom operations” guide with details on the new slice_transform argument.

Changed

  • io: File reads now detect when the whole file or an entire plane can be read contiguously and skip the per-plane seeks used previously, greatly improving read speed for those slicing patterns.

  • sdk: ImageArray now clones individual planes while streaming instead of copying the entire cube up front, avoiding allocating the full cube twice in memory.

  • python: VectorizedUnaryOp now memoises its dummy-input shape/dtype probe, avoiding repeated Python calls when streaming.

  • dynarray: Array creation now pre-allocates vector capacity, reducing reallocations.

Fixed

  • sdk: Fixed a source slice calculation bug in the binning operation.

  • python: Fixed a few remaining Image.header to Image.meta conversions that were missed in the v1.0 rename (bundled docs example and ml.py).

[1.0.0-beta.2] - 2026-06-03

Added

  • sdk: Added deterministic structural UUIDs for image pipeline nodes via the new Image::uuid method.

  • python: Exposed image pipeline UUIDs through the Image.uuid property.

  • control: Added explicit StageController and SimulatedStageController optical parameters for focal length, object distance, pixel pitch, and slit width, plus derived pixel/slit field-of-view accessors.

  • control: Added a ControlNotFound error variant for clearer missing-control failures.

Changed

  • Breaking, control: Renamed CameraError to ControlError to better match the scope of camera and stage-control errors.

  • Breaking, control: Replaced the stage-controller lens-size helper with explicit focal length, object distance, pixel pitch, and slit width parameters.

  • control: StageController now reports clearer errors when required motion parameters such as velocity/framerate or distance are missing.

  • control: Simulated stage controllers now flip BSQ sources to BIL internally, so image-backed streaming has the expected orientation.

  • examples: Updated the camera example to demonstrate the revised streaming flow.

  • docs: Added missing Python documentation for select_mask, select, select_bands, and preprocessing.savgol.

Fixed

  • sdk: Strided slices with an open-ended stop now allocate ceil(n / step) elements to match Python/ndarray slice semantics, fixing a broadcast shape error when the axis length is not divisible by the step.

  • sdk: Binary operations now propagate upstream image errors instead of causing a panic.

  • control: Camera stream shutdown now uses timeouts when sending stop/end commands, avoiding hangs in stream teardown.

  • python: CameraStream.get_frame now releases the GIL while waiting for frames, preventing deadlocks from blocking Python.

[1.0.0-beta.1] - 2026-06-03

Added

  • python: Type stub generation via a new pystubs CLI driven from build.rs, so the Python API now ships with .pyi stubs.

  • python: Added SimulatedStageController to the control module — wraps any Camera for easy testing of stage-driven applications.

  • python: Exposed the generic StageMachine API to Python.

  • docs: Docs are now built for both current and previous versions, making it possible to keep using old SDK versions.

Changed

  • Breaking, python: Major API rename for v1.0 to drop the redundant HS/HSI prefixes.

    • HSImageImage

    • InMemoryCubeImageArray

    • HSIFileImageFile

    • HSCameraCamera

    • HSIHeaderImageMeta

    • HSIErrorError

  • Breaking, python: Python package is now qtec_hv_sdk (suggested usage: import qtec_hv_sdk as hs).

  • Breaking, c-ffi: Renamed the public image API for v1.0 (hv_hs_image_t/hv_hs_image_* to hv_image_t/hv_image_*) and metadata API (hv_hsi_header_t/hv_hsi_header_* to hv_image_meta_t/hv_image_meta_*).

  • c-ffi: Restored inspectable public metadata structs with grouped v1 fields on hv_image_meta_t, including camera, spectral, spatial, radiometric, temporal, calibration, sensor, encoding, and display metadata.

  • Breaking, general: Internal hsi-cam crate renamed to hsi-control; it now exports its own Python submodule using the new PyO3 module syntax.

Removed

  • python: write_meta function (no longer has a use case).

  • docs: The WASM-based live demo, including all bundled pyodide wheels. The CI was running out of space and the demo was already out of date; it can be cherry-picked back from history later if needed.

Fixed

  • python: Import bug in the annotations submodule.

[0.10.2] - 2026-05-11

Added

  • python: Added bindings for set_bit_mode and get_bit_mode.

  • fix: Dark frame generation to handle multiple multiple data types.

  • fix: Use stream.stop() after exiting stream.

[0.10.1] - 2026-05-07

Added

  • annotations module for working with annotations. The module is compatible with files produced by Hypervision Explorer

  • Images now have a new method select_mask_from_descriptor which uses a descriptor as a mask.

  • Generic StageMachine interface to support multiple linear recording stage types.

  • Add move_direction to StageController for continuous movement.

  • python: The annotations module and select_mask_from_descriptor method are also available in the Python API.

  • python: Add move_direction to StageController.

Changed

  • Added optional n_frames parameter to CameraInterface::stream (HSCamera.stream in Python).

Fixed

  • Full camera buffers previously lead to a block (caused by a data race) in the camera thread. The streams now use timeouts to keep checking for stop-commands even when the frame buffer is full.

  • Slicing error in PAM/ENVI and TIFF files causing stepped slices to fail fixed.

[0.10.0] - 2026-04-15

Added

  • HSIStream now has a stop method for stopping infinite streams.

  • The SDK now has logging support.

  • Frames now contain metadata with the frame’s sequence number, timestamp, and whether it was dropped.

  • python: Stream type now supports stopping using either a stop method or the with statement.

  • python: Added support for direct camera streaming through the CameraStream type. The API is the same as Stream.

  • python: Logging is integrated with the Python logging module.

  • python: Stream types now return a FrameMeta object along with the frame data on new frames.

  • python: HSImage.ufunc as well as the @operation decorator now accept a FrameMeta object as the first argument.

  • python: Added a throughput test script for benchmarking camera connection performance.

  • c-ffi: Added hv_frame_meta type to support the new internal API.

Changed

  • Dropped camera frames are now inserted as blank frames to maintain correct spatial information.

  • Buffers between threads are now bounded with a fixed size of 64 elements.

Fixed

  • Fixed bug in ImgCamera which caused the bands to be incorrectly chosen for BSQ images.

  • python: Fixed bug in the preprocessing module causing the snv and savgol functions to not work.

[0.9.2] - 2026-03-10

Added

  • toggle_lights method added to StageController (also in the Python API)

  • Added get_analog_gain/set_analog_gain methods to HSCamera in the Python API.

Changed

  • HSCamera and StageController now report connection errors clearly and immediately upon object creation.

[0.9.1] - 2026-02-18

Added

  • set_lights method to StageController. Activates lights and autoimatically deactivates them after a specified duration. Exposed timed light control via the Python extension.

[0.9.0] - 2026-01-29

Added

  • StageController is now available in the Python API.

  • Basic 2D Convolution operation along the streaming axis of an image. This operation is not fully generic wrt. interleave which limits its use in streaming applications.

  • New debug_info method on HSImage to print information about a given image/operation. In Python, this is available through the __repr__ dunder method.

  • New parents method on HSImage to get any parents of a given image/operation. This can be used to reconstruct the graph of dependents for an output operation. The get_tree method in the Python API exemplifies how this can be done.

Changed

  • Dot products are more efficient for certain interleaves and when slicing along the second dimension of a 2d matrix.

  • Binning now simply calculates the sum of the binned values instead of the mean. This makes the operation more generic and averaging can still easily be performed afterwards.

Fixed

  • The select_mask operation now correctly handles slicing. A number of bugs prevented this from working properly with certain combinations of interleave and other operations.

[0.8.3] - 2025-12-04

Changed

  • HSIError::DynArrayError errors now display the inner error as part of its message

Fixed

  • Bug in the band selection logic. The end index of slices is exclusive but this was not corrected for previously.

[0.8.2] - 2025-11-10

Changed

  • New public repository

Fixed

  • Bug in the band selection logic. The band selection did not calculate the indices correctly, which caused out-of-bounds errors.

[0.8.1] - 2025-10-24

Fixed

  • The C/C++ reference in the docs is now included correctly.

  • The documentation’s live demo has been fixed.

[0.8.0] - 2025-10-22

Added

  • sdk: HSImage method stream added - it starts a concurrent stream with a full slice.

  • sdk: Initial experimental support for qamlib-rs (internal use only).

  • c-ffi: Debug format functions added for most types.

  • c-ffi: hv_ensure_dtype method added.

  • c-ffi: You can now edit/get extra metadata in the header with the hv_image_meta_get/hv_image_meta_set methods.

  • python: The python API now supports the stream method and the HSIStream type. Support is still experimental.

  • apps: New cli application hv for performing basic operations. Currently, the application can just show file information.

  • docs: New unified API documentation and guides. Includes a wasm-based demo of the Python API.

Changed

  • sdk: HSImage method slice_iter changed to stream_slice.

  • sdk: HSImage method slice_array changed to array_slice.

  • sdk: HSImage method plane_axis changed to array_plane.

  • sdk: HSImage method full changed to array_full.

  • sdk: HSImage method plane_axis_crop changed to array_plane_crop.

Deprecated

  • sdk: HSImage method array_plane_crop is deprecated. Instead, use slice followed by array_plane.

Removed

  • apps: Old unused applications (hsi-viewer).

Fixed

  • A critical bug in the camera API that prevented the camera from streaming.

[0.7.3] - 2025-09-27

Added

  • Scalar operations for images (both left and right hand side)

  • HSIStream now provides a synchronous mode. This is useful for applying lightweight operations. Most simple operations, including as_dtype, nan_to_num, etc. now use this mode.

  • The C and Python APIs support the added scalar operations.

[0.7.2] - 2025-08-19

Added

  • C bindings for the entire SDK.

  • Doxygen documentation for the C bindings.

[0.7.1] - 2025-08-18

Added

  • Small PCA/projection sample program.

  • A rust write function similar to the one implemented for the Python API.

Fixed

  • A bug in InterleaveChangeOperation where the shape was not correctly updated, resulting in broadcasting errors in many cases.

[0.7.0] - 2025-08-10

This update introduces infinite data streams and integration with the HyperVision 1700 camera.

Added

  • Initial generic HyperVision camera API.

  • Interface layer for the quark-backend REST API.

  • Image-backed camera type that can simulate a real camera.

  • Initial integration between cameras and the HSImage/HSImageOps API.

  • Initial Python API reflecting the Rust camera APIs.

  • An open function in the Rust API that detects file extension and header/data file for ENVI files. It is an improvement to the Python API version and the Python function now just calls the Rust function internally.

Changed

  • The framework uses a new ShapeMeta type to allow for infinite streams of hsi data.

  • The Python calibration routines now support setting a target interleave and uses the rust-based ensure_dtype method.

  • Fixed a bug in the PAM header writing code when calculating the PAM shape.

  • The documentation is now published to qtec-mono.

  • The image-tiff fork has been rebased onto the latest main branch (version 0.10)

  • The HSIReader trait has been removed completely. Having individual open methods makes it easier to account for file type differences.

Fixed

  • A bug in MeanAxisOp, where it would not work correctly in certain instances.

  • A bug in InterleaveChange, where the shape was not calculated correctly for BSQ output.

  • A deprecated use of PyTuple became a bug when updating the pyo3 version.

  • A bug in the PAM header writing code where the shape calculation would be wrong.

  • An issue with the ENVI header parser not working correctly for files with CRLF endings. A new test has been added to check for these special cases.

[0.6.3] - 2025-06-09

Added

  • NanToNum operation that replaces NaN values with a specified value.

Changed

  • predictor in the Python API now replaces nan values with 0 before calling the model’s predict function.

[0.6.2] - 2025-06-01

Added

  • Operation decorator for easy adaptation of Python functions into the SDK.

  • Predictor function wrapper for easily integrating scikit-learn models into the framework.

  • Pca-model function wrapper for efficient integration of projection models.

  • Documentation has been updated with new information.

Fixed

  • The ufunc (VectorizedUnaryOp) operator did not correctly adjust the slice for the source image.

[0.6.1] - 2025-05-23

Added

  • New Binning operation.

Changed

  • Combining slices now skips single indexes, which is more efficient.

  • Streams now return Result for each element, which makes proper error handling possible.

  • Array reconstruction now prints channel-related errors to stderr for easier debugging.

Fixed

  • Bug in interleave change that caused slices not to be correctly calculated.

  • Added an extra GIL lock to VectorizedUnaryOp which caused segfaults.

[0.6.0] - 2025-05-02

Added

  • Data processing is now performed using the HSIStream type which uses Rayon and crossbeam to asynchronously execute pipelines.

  • Slicing is now done using the new SliceElem and SliceDescriptor types that are based specifically on HSI terminology.

  • Slicing shapes are now validated and returns an appropriate error when relevant.

  • Added a mask selection operation, which uses a boolean mask array to select spatial pixels.

Changed

  • The HSIError::ShapeError variant now has a backtrace. This may be added to other errors in the future.

  • Switched to the nightly compiler.

  • Debug symbols have been removed from the release build.

[0.5.6] - 2025-03-13

Changed

  • Package/library name is now qtec-hv-sdk. This prevents naming clashes and increases clarity. The Python import is still hsi.

[0.5.5] - 2025-03-12

Changed

  • Now using a manylinux_2_28 based image to build the binary packages.

  • The public package upload now only publishes the binary packages.

[0.5.4] - 2025-03-10

Changed

[0.5.3] - 2025-03-03

Changed

  • Dynarray version bumped to 0.5.3 to make it equivalent to the rest of the packages. Since they are updated together, this makes versions much simpler to understand.

Fixed

  • Updated CI to fix Windows build.

[0.5.2] - 2025-02-25

Added

  • Interleave change operation

Changed

  • Select operation now uses Array2 instead of a vector of tuples.

  • The Python API for select now automatically converts Numpy arrays, list of lists, and lists of tuples to Array2 internally.

Fixed

  • Blas inclusion did not work properly on windows. It has now been made optional and is not used in the automated builds. The current impact on performance is negligible.

  • Modified CI to correctly build for linux/windows distributions and added a source distribution for easy local compilation.

  • Some doc pages didn’t build correctly due to a missing dependency.

[0.5.1] - 2025-01-28

Added

  • Select operation that allows passing a list of arbitrary line/sample coordinates to select a spectral subset of an image. Useful for subsampling patterns.

  • random_sample utility function for the Python extension to easily generate random samples (currently with repetition).

Changed

  • Tiff default interleave is now BSQ, which is the most intuitive format when viewing the files in regular image editors.

Fixed

  • A few errors in the documentation (recipes section).

[0.5.0] - 2024-11-06

Added

  • Matrix-vector and Matrix-matrix product support.

  • Basic tiff support added.

  • Documentation of operations and missing basic types in the Python docs.

  • Header modification operation (will likely change since it is cumbersome to use).

  • Added blas support.

Changed

  • Mean now uses a memory efficient approach for BSQ. This should be adapted to other reductions.

Fixed

  • Interleave bugs everywhere

  • Slicing bugs in many places.

[0.4.0] - 2024-08-02

Added

  • HSImage trait for a unified interface for image types and operations.

  • HSImageOps trait for arithmetic operations (addition, subtraction, multiplication, division) as well as type changes, numeric clamping, and axis reduction functions (mean, std, var, sum).

  • Lazy slicing through slice_iter for building compound operations.

  • InMemoryCube can now be created directly from an array.

  • (python) Preprocessing module with SNV and reflectance calibration functions.

  • (python) Magic methods implemented for arithmetic operations.

  • (python) Index magic method implemented as lazy slicing.

  • (python) Can create new HSImages from NumPy arrays.

Changed

  • HSIFile and InMemoryCube now work through the unified HSImage trait.

  • (python) Writing now works directly on HSImage objects.

Fixed

  • Multiple bugs related to slicing and indexing.

Deprecated

  • (python) HSIFile is no longer used in the python API.

[0.3.0] - 2024-06-03

Added

  • Read individual planes of HSI files.

  • Added in-memory HSI type. The interface is likely to change.

Changed

  • Refactored crate into several sub-crates for each specific area of functionality.

Fixed

  • Bug in hsi-cli where the header would not be updated.

  • Bug where files would be read incorrectly.

[0.2.0]

Added

  • Conversion between PAM, ENVI, and yaml hyperspectral file formats.

  • Conversion between HSI interleave formats.

  • Memory efficient implementation only reads and processes small chunks of a file at a time.

  • Iterator implementations for processing hyperspectral data.

  • (cli) A simple tool for converting between file formats and interleaves.