Skip to contents

annotatR (development version)

  • Stopping a local control listener now cancels its pending expiry callback. This releases the stopped service and prevents subsequent Shiny module tests from waiting for the old expiry time. Active-service expiry is preserved.

  • TIFF image reads, TIFF mask imports and the TIFF raster fallback now decode in a clean R subprocess to avoid native callback failures after ImageMagick has been used. Pixel values, attributes and caller-specific conversions are preserved. Decoding requires an executable Rscript and writable temporary storage. Set options(annotatR.tiff_timeout = 120L) to control the timeout in whole seconds (default 120). Failed or timed-out decoding returns an error. This remains eager decoding; isolation does not provide bounded image memory or native window reads.

annotatR 0.2.0

A partner contract for the qupflowR package, a testable app builder with an optional local control service, hyperspectral metadata and windowed readers, and deep-learning training datasets. The existing API, S3 classes and files remain compatible; behaviour changes are listed under Changes.

Partner interoperability (qupflowR)

  • at_interop_capabilities() reports the I0-I3 profiles with status, implemented, available and reason, limits, formats, HSI backends and a capability digest. Direct control (I2) and embedding (I3) are reported as planned until they are qualified against a real qupflowR client.
  • at_interop_manifest() writes a sanitised annotatr-handoff-v1 manifest: content-derived image ids, dimensions, levels, planes, coordinate convention, band tables, HSI value semantics, calibration/transform digests and annotation revisions, without local paths. at_annotation_revision() gives the content revision partners use as expected_revision.
  • at_export_qupflowr() writes a staged, SHA-256-inventoried handoff directory (QuPath GeoJSON, GeoJSON, integer masks with legends, NPY, CSV, RDS, HSI manifest). Its digest follows qupflowR’s canonical-JSON bundle digest rule.
  • at_import_qupflowr() verifies inventory, schema, major version, id joins, labels, mask dimensions and legends, and returns namespaced annotatR objects with a conversion report.
  • at_stage_qupflowr() and at_commit_qupflowr() apply partner changes as an explicit, revision-checked, idempotent diff that never overwrites reviewed or locked annotations.
  • JSON Schemas ship under inst/schema/ and are enforced by a small built-in validator. Errors are classified (at_validation_error, at_conflict_error, at_io_error, at_protocol_error, at_auth_error, at_limit_error, at_capability_error) with machine-readable codes.

App builder and control service

Hyperspectral cubes

  • at_hsi_meta(), at_read_stats(), at_convert_values(), at_band_operations() and at_band_view().
  • at_bands() gains fwhm, order and wavelength_status columns; missing or duplicated wavelengths are flagged, never interpolated.
  • The ENVI reader validates the header and payload length, honours header offset (a sentinel header byte no longer becomes a pixel), supports uint32, keeps FWHM, band names, ignore value, scale factor and gain/offset values, and reads windows by seeking instead of loading the cube.
  • TIVITA SpecCubes are read through at_tivita_profile() or a <cube>.tivita.json sidecar with windowed reads; a file that matches no declared profile is refused.
  • The Cubert backend was rewritten against the cuvis.r 0.1.0 API (the previous call did not exist) and records SDK, processing mode and calibration provenance; at_cubert_export_envi() writes the portable ENVI fallback. Without the SDK the backend reports itself unavailable.
  • A TIFF is spectral only with declared wavelengths.
  • at_tile() enforces options(annotatR.max_tile_bytes); app previews read only the displayed bands.

Training datasets

Changes

  • at_write_qupath() now writes the QuPath 0.4+ dialect by default (objectType, classification.color, UUID feature ids plus annotatR ids in properties.metadata), verified with QuPath 0.7.0. Use dialect = "legacy" for the 0.1 form. at_read_qupath() reads both, including derived classes, measurements, planes, nuclei and ellipse flags.
  • GeoJSON writers use 17 significant digits so coordinates round-trip exactly.
  • at_roi_circle() and at_roi_ellipse() record attributes$shape.
  • Numeric choice arguments such as bits = 8L and connectivity = 4L are accepted; argument validation errors now carry class at_validation_error.
  • Navigating in the app keeps the edited project in its own queue entry, and Shift+Enter stores the current project before advancing.
  • App export file names are sanitised and unique.
  • R CMD build excludes a local inst/shiny/annotatR/hsi-workbench/ directory.

annotatR 0.0.1

Initial development release.

Images and backends

Regions of interest and geometry

Masks

  • at_mask() produces binary, labelled, or multi-class integer masks with a documented pixel-coverage contract, six overlap policies, and a self-describing legend. A values argument pins labels to explicit integer codes, and the "bitor" overlap policy bitwise-ORs overlapping values to build bitfield masks (e.g. an artefact layer where a pixel is specular | blood). Helpers: at_mask_stats(), at_mask_boundary(), at_mask_preview(), at_mask_stack().
  • at_mask_derive() combines layer masks into a derived training mask (state WHERE anatomy == keep AND artefact == 0 AND state != background).
  • at_mask_agreement() scores two masks with per-class Dice / IoU and an overall accuracy and Cohen’s kappa (e.g. against a .npy ground truth).
  • at_write_mask() writes TIFF/PNG/RDS with a sidecar JSON legend; at_read_mask() polygonises a mask back into editable ROIs. at_write_npy() / at_read_npy() losslessly interchange integer masks (incl. bitfields) with NumPy .npy, the format used by external HSI annotation tools.

Application

  • at_annotate() launches a resumable, keyboard-first batch annotation app with live mask preview, built on shiny and a deep-zoom canvas widget.