Skip to content

Changelog

0.5.1 - 2026-07-26

Added

  • Added -3024 HU (outside the CT reconstruction field of view) to the pool of sentinel values recognised by automatic sentinel detection, alongside the existing -2048, -1024, -1000, 0 and -32768.
  • Added versioned, machine-readable filter capability metadata (FILTER_CAPABILITIES, get_filter_capabilities, CAPABILITIES_SCHEMA_VERSION) describing input/kernel dimensionality, plane execution and averaging, rotation pooling, supported and effective boundaries, Riesz orders, structure-tensor steering, and anisotropic-spacing behaviour, so compliance tooling no longer has to infer them from signatures.
  • Every executed pipeline filter step now records params_requested (the parameters as supplied) and params_effective (the arguments actually passed to the filter, including pipeline-injected values such as spacing_mm and the Riesz variant dispatch) in the run log, so a parameter that is defaulted, substituted, or cannot be applied exactly is always visible. Arrays are recorded as compact shape descriptors rather than raw data.
  • The FFT-based filters (simoncelli_wavelet, riesz_transform, riesz_log, riesz_simoncelli) now honour the boundary parameter through a defined pad-filter-crop procedure instead of always being periodic. Periodic remains the default, so existing results are unchanged; riesz_transform, riesz_log and riesz_simoncelli gain a boundary argument.

Changed

  • Corrected the IBSI 2 compliance reporting: test 10.a is no longer described as structure-tensor aligned (it is unsteered), a skipped test can no longer be reported as passing, Phase 1 results now separate the strict 3D total from the broader volumetric total with the four 2D Gabor tests named, and the single Phase 2 feature with no published consensus value (8.B stat_qcod) is shown explicitly as coverage-only instead of being silently omitted. Both compliance pages now record provenance (package version, IBSI 2 reference manual version, reference dataset source and content hashes) and Phase 1 documents one exact, reproducible named test.

Fixed

  • Gabor filtering now scales its 2D kernel using the true in-plane voxel spacing of each plane instead of deriving every scale from the first spacing component. This corrects results for anisotropic voxels when average_over_planes=True (the planes containing the through-plane axis were previously computed with the wrong physical scale). Isotropic in-plane spacing keeps the existing code path and is bit-for-bit unchanged, so IBSI Gabor results are unaffected. The anisotropic-spacing warning has been removed because the case is now handled correctly rather than approximated.
  • IBSI 2 Phase 1 verification now requests the padding each test specifies for the Riesz filters (zero padding for 9.a/9.b.1/10.a, nearest for 10.b.1) instead of relying on the periodic default, measurably improving agreement with the published reference response maps.
  • The auto-detected sentinel warning no longer rounds a near-total sentinel fraction up to "100.0% of voxels", which wrongly implied that no voxels remained for feature extraction. Fractions above 99.95% are now reported as ">99.9%" (a literal 100.0% is shown only when every voxel is the sentinel), and the message states how many voxels remain valid. The full-precision sentinel_proportion recorded in the run log is unchanged.
  • The pipeline no longer silently discards a requested boundary for the Simoncelli and Riesz filters, and an unsupported boundary value now raises a clear error instead of falling back to mirror padding. Each filter step records both the requested and the effective boundary in the run log.

0.5.0 - 2026-07-12

Optimized

  • Cache the Riesz frequency-domain transfer function (depends only on shape and order), making riesz_transform (and riesz_log/riesz_simoncelli) ~1.9-2.5x faster on repeat same-shape calls with byte-identical output.
  • Cache the Simoncelli wavelet frequency-domain transfer function (depends only on shape and level), making simoncelli_wavelet ~1.8-2.9x faster on repeat same-shape calls with byte-identical output.
  • Faster Moran's I and Geary's C spatial-intensity features (about 2x on larger ROIs) by exploiting the symmetry of the inverse-distance weights and letting the O(N^2) inner loop vectorise; byte-identical.
  • Faster shared nonzero-bounding-box and ROI min/max scans via single-pass numba kernels (with numpy fallbacks for small or non-float inputs), reused across feature families and memoised per extraction pass; byte-identical.
  • Much faster preprocessing via numba kernels and ROI-bounded work: image resampling up to ~35-66x, discretise_image ~5-9x, resegment_mask ~4x, and keep_largest_component ~35x on CT-sized volumes; bit-identical for discrete outputs and within 1e-9 for linear resampling.
  • Reduce redundant array recomputation in the GLCM/GLRLM/GLDZM/NGLDM/NGTDM feature calculations (~7% faster per family); byte-identical output.
  • Replace the GLDZM distance transform with a numba chamfer kernel (~3-4x faster on that step); distances are byte-identical to the previous scipy result.
  • Share the resampled mask between the morphological and intensity masks when they are in sync (and drop a redundant mask copy), speeding multi-config pipeline runs with byte-identical output.
  • Speed up texture ROI voxel counting on float masks (~5x) with a dtype-gated nonzero count; results are byte-identical.
  • Substantially faster texture feature extraction (GLCM/GLRLM/GLSZM/GLDZM/NGTDM/NGLDM): vectorised the GLSZM matrix build, derive GLCM Ng_eff from the ROI bounding box, crop all texture work to the ROI bounding box to eliminate full-volume float64 mask scans, gate matrix computation to the requested families, and parallelise the zone-labelling kernel. Byte-identical results, roughly 1.4-15x faster on CT-sized and sparse volumes.

0.4.2 - 2026-05-16

Changed

  • Extended CI to lint tests, added a separate JIT smoke check outside coverage accounting, and made the MkDocs-published changelog the towncrier source with root changelog sync support.

Fixed

  • Fixed IBSI 1 compliance benchmarks that failed due to recent pipeline default changes by explicitly restricting resegment and filter_outliers steps to the intensity mask in standard compliance configurations (Configs C, D, E).
  • Fixed compartment-specific pipeline semantics so resegment and filter_outliers update morphology masks by default, source masks constrain morphology masks after resampling, deduplication treats mask-narrowing steps as morphology dependencies, and describe_features() reports mask usage plus effective apply_to targets. Nonzero multi-label mask values are now treated as ROI membership rather than numeric weights across preprocessing, morphology, and texture calculations, while binarize_mask remains the explicit label-selection step. Configuration exports and processing logs now include mask semantics, package/schema metadata, configuration snapshots, deduplication settings, and effective source/sentinel details for reproducible runs on other machines.
  • Fixed deduplication signatures to preserve preprocessing step order, corrected continuous-IVH deduplication dependency detection, applied per-frame DICOM rescale transforms for multiframe files, and propagated DICOM SEG alignment controls through reference-aware loading.

Optimized

  • Removed redundant initializations of min_rot and max_rot arrays in _ombb_extents_numba to slightly improve morphology calculation efficiency.

0.4.1 - 2026-05-05

Changed

  • load_image and load_and_merge_images now accept subvoxel_tolerance, subvoxel_warning_threshold, and min_overlap_fraction parameters for configurable sub-voxel alignment handling when repositioning cropped masks. RadiomicsPipeline.run() exposes the same controls via mask_subvoxel_tolerance, mask_subvoxel_warning_threshold, and mask_min_overlap_fraction. Repositioning settings are recorded in the pipeline run log.

Fixed

  • Expanded describe_features() so feature catalog rows record ordered preprocessing metadata, repeated step parameters, source-mode context, and extraction-step parameters in machine-readable columns.
  • Fixed multi-configuration deduplication so texture, histogram, and IVH families no longer reuse each other's cached results when they share the same preprocessing signature.
  • Fixed physical geometry validation for masks and source masks, including direction-aware cropped repositioning and axis-transpose metadata handling.
  • Fixed silent empty-array return when a repositioned mask has no overlap with the reference image. This now raises a ValueError by default (controlled by min_overlap_fraction) to prevent undetected wrong-patient mask loading. Set min_overlap_fraction=0.0 to restore the previous warn-and-continue behaviour.
  • Fixed texture subfamily aliases, NIfTI direction normalization, direction-aware geometry updates, and per-slice DICOM rescale handling.
  • Updated configuration validation so serialized configs using current resampling, discretisation, and IVH runtime parameters no longer emit false unknown-parameter warnings.

[0.4.0] - 2026-04-14

Added

  • Added describe_features() method to RadiomicsPipeline that returns a DataFrame cataloguing every feature the pipeline will produce, with columns for configuration name, feature identity (name, IBSI code, family, broad family group), discretisation/resampling/filter metadata. Useful for exporting data dictionaries and filtering features before extraction.

Changed

  • Pipeline runs now always return a complete, predictable set of feature columns for every configuration. When the ROI is empty after preprocessing (EmptyROIMaskError), a full NaN-valued Series is returned instead of raising an error, and processing continues to the next configuration. Partial extraction failures (e.g., PCA with ≤3 voxels, mesh computation errors, empty texture matrices) are backfilled with NaN so that no feature keys are silently dropped. A new FEATURE_NAMES registry in pictologics.features enumerates all 174 expected feature names by family.
  • pipeline.run(subject_id=...) no longer injects subject_id into each configuration's feature Series. The parameter is now used exclusively for the processing log. To include subject identifiers in formatted output, pass them via format_results(meta={"subject_id": ...}).

0.3.5 - 2026-02-19

Changed

  • Configuration Loading Behavior: load_configs(), from_yaml(), from_json(), and from_dict() now default to loading only the provided configurations, without including standard predefined configs. Pass load_standard=True to include standard configs alongside loaded ones. RadiomicsPipeline() default constructor behavior is unchanged.

0.3.4 - 2026-02-14

Fixed

  • Memory Exhaustion Issue: Resolved a critical issue where resampled background voxels (value 0) were included in the ROI if they fell within the resegment range. The pipeline now explicitly applies the source_mask to the intensity_mask after resampling when source_mode="auto" or an explicit source mask is used. This prevents memory explosions for small ROIs in large volumes with sentinel backgrounds.
  • Pipeline Configuration Serialization: Fixed a bug where source_mode and sentinel_value were lost during serialization (to_dict/to_yaml).
  • Sentinel Detection: Fixed detection logic to correctly handle auto-generated full masks.

Changed

  • Documentation: Updated Data Loading and Pipeline user guides to clarify the usage of source_mode="auto" vs "full_image" and its impact on memory and correctness.

0.3.3 - 2026-02-11

Changed

  • Sentinel Value Implementation: Implemented proper handling of sentinel values in the pipeline to assure that they do not influence the feature extraction.
  • Complete overhaul of User Guide: Rewrote the user guide to improve clarity and organization.
  • Benchmark Methodology Updates: Refined timing methods for benchmarking with optimized measurement techniques, resulting in up to 40% faster execution for PyRadiomics compared to previous implementations. Therefore speed improvements of pictologics are now more modest.

0.3.2 - 2026-02-01

Added

  • Feature Deduplication System: Intelligent optimization for multi-configuration pipelines:
    • Automatically detects when configurations share preprocessing steps but differ only in discretization
    • Computes discretization-independent features (morphology, intensity) once and reuses across configurations
    • deduplication_stats property provides reuse/compute statistics after each run
    • Hash-based signature comparison using SHA256 for exact parameter matching
    • Versioned rules system (DeduplicationRules) for reproducibility

Changed

  • Deduplication enabled by default: RadiomicsPipeline(deduplicate=True) is now the default behavior
  • Documentation updated:
    • Case examples simplified to reflect default deduplication behavior
    • Benchmark page clarifies methodology (raw timing without caching) and notes additional speedups with deduplication

0.3.1 - 2026-01-31

Added

  • Pipeline Configuration Serialization: Full YAML/JSON export/import for RadiomicsPipeline configurations:
    • save_configs() / load_configs(): File-based configuration persistence
    • to_yaml() / from_yaml(): String-based YAML serialization
    • to_json() / from_json(): String-based JSON serialization
    • to_dict() / from_dict(): Dictionary conversion for programmatic use
  • Configuration Management Methods:
    • add_config(): Register custom configurations
    • get_config(): Retrieve configuration by name (deep copy)
    • remove_config(): Delete configurations
    • list_configs(): List all registered configuration names
    • merge_configs(): Combine configurations from multiple pipelines
  • Template System: YAML-based configuration templates in pictologics/templates/:
    • Standard configurations now loaded from standard_configs.yaml
    • Template loading API: list_template_files(), load_template_file(), get_standard_templates(), get_all_templates(), get_template_metadata()
  • Schema Versioning: Configuration files include schema_version for forward compatibility and automatic migration
  • Configuration Validation: Opt-in validation via validate=True parameter logs warnings for unknown steps/parameters
  • Documentation: New "Predefined Configurations" user guide page with comprehensive examples including end-to-end multi-site study workflow

Changed

  • Standard configurations (standard_fbn_*, standard_fbs_*) now loaded from YAML templates instead of hardcoded dictionaries
  • Updated pipeline.md documentation with condensed configuration section and cross-references

Dependencies

  • Added pyyaml>=6.0 as core dependency for YAML serialization

0.3.0 - 2026-01-25

Added

  • IBSI 2 Convolutional Filters: Complete filter module (pictologics/filters/) with:
    • Mean filter (3D)
    • Laplacian of Gaussian (LoG)
    • Laws texture energy filters (3D rotation-invariant)
    • Gabor filters (2D per-slice)
    • Wavelet decomposition (Haar, Daubechies, Coiflet, Symlet families)
    • Simoncelli steerable pyramid
  • IBSI 2 Phase 1 Compliance: Filter response map validation against digital phantoms
  • IBSI 2 Phase 2 Compliance: Feature extraction from filtered images validated
  • IBSI 2 Phase 3 Compliance: Multi-modality reproducibility validation across 51 patients × 3 modalities compared to 9 team submissions
  • Filter Pipeline Integration: New filter step in RadiomicsPipeline for seamless filtered feature extraction
  • Mask Binarization Pipeline Step: New binarize_mask preprocessing step with configurable threshold, mask_values (int/list/range tuple), and apply_to targeting.

Changed

  • Updated mkdocs.yml with IBSI 2 Phase 1, 2, 3 navigation
  • Expanded pipeline documentation with filter usage examples and binarization

Fixed

  • IBSI 1 Compliance (Morphology): Achieved passing values for Compactness 2 (BQWJ) and Asphericity (25C7) in Configs C/D/E and texture matrices in config D by binarizing masks before resampling.

0.2.0 - 2026-01-06

Added

  • DICOM Database Utility: DicomDatabase class for parsing complex DICOM folder hierarchies with Patient → Study → Series → Instance traversal, multi-phase detection, and DataFrame/JSON/CSV exports
  • DICOM SEG Loader: load_seg() for loading DICOM Segmentation objects with multi-segment handling, geometry alignment, and seamless auto-detection in load_image()
  • DICOM SR Parser: SRDocument class for parsing Structured Reports with measurement extraction, CSV/JSON export, and batch processing via SRDocument.from_folders()
  • DICOM Multi-Phase Support: load_image() now supports multi-phase DICOM series with dataset_index, plus get_dicom_phases() for phase discovery
  • Visualization Utility: visualize_slices() for interactive viewing and save_slices() for batch export with window/level normalization and colormap options
  • Cropped Image Repositioning: load_image() and load_and_merge_images() support repositioning cropped masks into reference volume coordinate space
  • Intensity Rescaling: apply_rescale parameter in load_image and related functions to toggle DICOM rescale slope/intercept application (default: True)
  • Sentinel Value Handling: Documentation and examples for handling sentinel values (e.g. -2048 in Siemens DICOMs) using the resegment preprocessing step
  • Dependencies: Added highdicom, matplotlib, pillow; updated pandas>=2.0.0

Optimized

  • Morphology Speedup: Implemented bounding box cropping for morphology features (mesh/moments), significantly accelerating extraction for sparse ROIs in large volumes
  • Texture Speedup: Added slice-level skipping to texture calculation to ignore empty z-slices, vastly improving performance for disjoint ROIs (e.g. multiple tumors)

Fixed

  • DICOM file loading improvements: proper Z-spacing, 3D SEG handling, direction matrix extraction

Changed

  • DicomDatabase uses shared split_dicom_phases() for consistent multi-phase detection
  • Comprehensive documentation updates for all new utilities

0.1.0 - 2025-12-28

Initial commit